0 is one of many falsey values in JavaScript. It seems like an odd choice, for a language with only a single type of number to have 0 be falsey. It harkens back to our C heritage where 0 was the only falsey value, it was the '\0' at the end of a string it was the NULL value that pointed to nothing, it was the negative response to a comparison. I JavaScript it has some clever uses, but mostly just serves to trip us up.
var nodes = [ { id: 0, val: 'a' } , { id: 1, val: 'b' } , { foo: 20 } , { id: 2, val: 'c' } ] // Broken! nodes.forEach(function (node) { if (node.id) { console.log(node.val) } })
Above is a common case where we are using the presence of the 'id' property to indicate an object is the kind of object we are expecting, and if it is doing something with it. In this case since 'id' is an incremental id starting at 0, we get the unexpected behavior that this code never logs 'a'.
var nodes = [ { id: 0, val: 'a' } , { id: 1, val: 'b' } , { foo: 20 } , { id: 2, val: 'c' } ] nodes.forEach(function (node) { if ('id' in node) { console.log(node.val) } })
One way to attack this is to check the properties membership in the object. It doesn't matter the value of the property, if it's there `"property" in object` returns truthy, however this also picks up inherited properties, and if you explicitly set an id to null to remove it from the set of things being operated on, this will still pick it up.
var nodes = [ { id: 0, val: 'a' } , { id: 1, val: 'b' } , { foo: 20 } , { id: null, val: 'c' } ] nodes.forEach(function (node) { if (node.id != null) { // tricky console.log(node.val) } })
Another way to attack it would be `!= null`. One of the most compelling use cases of double equal or not equal, the type coercing equality operators, is comparing to null, because it only catches null or undefined. Even this narrow use case is tricky to read, because most people have completely eliminated type coercive equality from their programs.
var nodes = [ { id: 0, val: 'a' } , { id: 1, val: 'b' } , { foo: 20 } , { id: null, val: 'c' } ] nodes.forEach(function (node) { if (typeof node.id !== 'undefined' && node.id !== null) { console.log(node.val) } })
That leaves us with this very verbose, but usually preferred form. In some environments you can reassign the value of the variable undefined, so it's safer to check for undefined using typeof. and using the triple equals, non-coercive equality checks you can be sure it is exactly not undefined and exactly not null. If you're going to be doing this check a lot it might be worth putting in it's own function!