0.1.5 • Published 7 years ago

babel-plugin-transform-hasnil v0.1.5

Weekly downloads
3
License
MIT
Repository
github
Last release
7 years ago

babel-plugin-transform-hasNil

With this babel plugin, use .hasNil to traverse chained object properties and determine whether any of them return null or undefined.

This plugin is inspired by babel-plugin-transform-isNil, however the use case and internals are different.

Examples

const house = { kitchen: { drawer: [ ] } }
const drawer = 'drawer'
const goTo = function(location) {
	return location
}

if(house.kitchen.hasNil) {	/* false */
	console.log('this will not run')
}

// with a string literal
if(house['kitchen'].hasNil) {	/* false */
	console.log('this will not run')
}

// with a variable
if(house.kitchen[drawer].hasNil) {	/* false */
	console.log('this will not run')
}

// with a function using bracket notation
if(house[goTo('kitchen')].drawer.hasNil) {	/* false */
	console.log('this will not run')
}

// with a number literal
if(house.kitchen.drawer[3].hasNil) {	/* true */
	console.log('this will run')
}

// you can chain as many properties as you want
if(house[goTo(kitchen)].drawer[3]['sub-drawer'].forks.hasNil) {	/* true */
	console.log('this will run')
}

if(house.basement.closet[3].hasNil) {	/* true */
	console.log('this will run')
}

// Unsupported:

// chaining functions using dot notation
if(house.foo().hasNil) {	/* will not work */
	console.log('this will not work')
}

// logical operators
if((house || { }).hasNil) {	/* will not work */
	console.log('this will not work')
}

Installation

Due to Babel not handling the Proxy object, this plugin is only compatible with Node versions >= 6.0.0.

First, add the babel-plugin-transform-hasnil package via your preferred package manager:

npm install --save-dev babel-plugin-transform-hasnil

Then register with babel, such as by using the .babelrc file.

{
	"plugins": [ "babel-plugin-transform-hasnil" ]
}

Benchmarking

Summary: using hasNil is not as fast as using pure logical operators or isNil (which compiles to the same thing). In general, however, this should only impact you if you're looping > 10,000 times.

Here's a benchmark:

const entry = { first: { second: [ { third: { fourth: { } } } ] } }

The goal is to determine whether first.second[0].third.fourth returns null or undefined.

Operator logic:

(entry === null) || (entry === undefined) || (entry.first === null) || (entry.first === undefined) || (entry.first.second === null) || (entry.first.second === undefined) || (entry.first.second[0] === null) || (entry.first.second[0] === undefined) || (entry.first.second[0].third === null) || (entry.first.second[0].third === undefined) || (entry.first.second[0].third.fourth === null) || (entry.first.second[0].third.fourth === undefined)

isNil logic (does not support number literals such as [0]):

entry.isNil || entry.first.isNil || entry.first.second.isNil || (entry.first.second[0] === null) || (entry.first.second[0] === undefined) || (entry.first.second[0].third === null) || (entry.first.second[0].third === undefined) || (entry.first.second[0].third.fourth === null) || (entry.first.second[0].third.fourth === undefined)

hasNil logic:

entry.first.second[0].third.fourth.hasNil

Results:

cyclesoperatorisNilhasNil
1000 ms0 ms0 ms
1,000002
10,0001124

Contributing

Contributions are always welcome. You are encouraged to open issues and merge requests.

To run the tests, use npm run test.