For an interview this week, I was doing an online technical interview and under pressure, I quickly used a check to see if a value existed.
if (x) {
numberArray.push(x);
};
However, the data I was filtering contained values of 0 and null that needed to be treated differently and intentionally undeclared values that I would usually catch in my own code base or with a linter.
The rules I was trying to filter to could be summarized a such:
const v = 'abc' // exists
const w = 0 // exists
const x = null // nope
const y = undefined // nope
// const z // nope
My first attempt was equivalent to:
if (x == true) {
//Do stuff
}
'x' is cast to its boolean equivalent type, but 0 in javascript is the only number that casts to false.
The second area where it deviated is for cases like 'z' where a variable is unassigned or undefined and a comparison is being made, JavaScript will error out. This is not a great user experience.
Here are the results of a few of my tests until I eventually arrived at a way of checking a values existence that I needed.
Tests
The quick and dirty with some pitfalls
console.log(v ? 'exists': 'nope'); // exists
console.log(w ? 'exists': 'nope'); // nope
console.log(x ? 'exists': 'nope'); // nope
console.log(y ? 'exists': 'nope'); // nope
console.log(z ? 'exists': 'nope'); // ReferenceError: z is not defined
Captures 0, but now also null values and still errors out
console.log(v !== undefined ? 'exists': 'nope'); // exists
console.log(w !== undefined ? 'exists': 'nope'); // exists
console.log(x !== undefined ? 'exists': 'nope'); // exists
console.log(y !== undefined ? 'exists': 'nope'); // nope
console.log(z !== undefined ? 'exists': 'nope'); // ReferenceError: z is not defined
Closer, but now we are casting types again, and still doing the comparison that breaks on undeclared variables
console.log(v != null ? 'exists': 'nope'); // exists
console.log(w != null ? 'exists': 'nope'); // exists
console.log(x != null ? 'exists': 'nope'); // nope
console.log(y != null ? 'exists': 'nope'); // nope
console.log(z != null ? 'exists': 'nope'); // ReferenceError: z is not defined
The recommended safe way for most applications
console.log(typeof v !== 'undefined' ? 'exists': 'nope'); // exists
console.log(typeof w !== 'undefined' ? 'exists': 'nope'); // exists
console.log(typeof x !== 'undefined' ? 'exists': 'nope'); // exists
console.log(typeof y !== 'undefined' ? 'exists': 'nope'); // nope
console.log(typeof z !== 'undefined' ? 'exists': 'nope'); // nope
Extended version of the recommended method for the filter I needed
console.log(typeof v !== 'undefined' && v !== null ? 'exists': 'nope'); // exists
console.log(typeof w !== 'undefined' && w !== null ? 'exists': 'nope'); // exists
console.log(typeof x !== 'undefined' && x !== null ? 'exists': 'nope'); // nope
console.log(typeof y !== 'undefined' && y !== null ? 'exists': 'nope'); // nope
console.log(typeof z !== 'undefined' && z !== null ? 'exists': 'nope'); // nope
TLDR:
use (typeof value !== 'undefined')
if (typeof value !== 'undefined') {
//Do stuff
}
Bonus:
While every number but 0 casts to true, booleans cast to a number are:
true -> 1
false -> 0
This leads to fun cases like:
-1 == true; // false
-1 == false // false
-1 ? true : false; // true
This is because after casting to types the equivalent expressions are:
-1 == 1; // false
-1 == 0; // false
true ? true : false; // true
Top comments (0)