Alternative to IF — logical operators with non-boolean values

&&, || and ?? operators return one of the two values used as their operands. The values can be of any type.

&&

value1 && value2 results in value2 when value1 is truthy and in value1 when value1 is falsy:

console.log(undefined && 'a'); //undefined
console.log(0 && 1); //0
console.log('a' && 'b'); //b

Basically, && is a shortcut for a function with a if statement:

function and(value1, value2) {
if (value1) return value2;
else return value1;
}

If the function and is used instead of && the code gets a bit longer:

console.log(and(undefined, 'a')); //undefined
console.log(and(0, 1)); //0
console.log(and('a', 'b')); //b

A typical use case of && is safely accessing a property of an object that can happen to be undefined.

Suppose we have an array of objects each describing a user. Some of the common properties are not defined in some users. The first user has name and score but no age. The second user has age but no name or score.

let users = [{ name: 'John', score: 10 }, { age: 31 }, { name: 'Joe', score: 0 }];

We want to print the lengths of the users’ names:

users.forEach(user => console.log(user.name.length));

After printing 4 (the length of John), the code produces an error Cannot read property ‘length’ of undefined because the second user object has no name property. && helps to avoid the error:

users.forEach(user => console.log(user.name && user.name.length));

Now the code prints the length of all user names: 4, undefined and 3.

||

value1 || value2 results in value2 when value1 is falsy and in value1 when it is truthy:

console.log(undefined || 'a'); //a
console.log(0 || 1); //1
console.log(false || true); //true
console.log('a' || 'b'); //a

Essentially, || is a shortcut for a function with a conditional statement:

function or(value1, value2) {
if (value1) return value1;
else return value2;
}

If in the code above || is replaced with function or, the output does not change but the code gets longer:

console.log(or(undefined, 'a')); //a
console.log(or(0, 1)); //1
console.log(or(false, true)); //true
console.log(or('a', 'b')); //a

|| operator is often used to replace undefined values, which would be displayed in a web page as undefined, with empty strings or default values. To illustrate the problem, let’s display the users’ data as a table unmodified.

tableBodyElement.innerHTML = users.reduce((t, o, idx) =>
t + `<tr><td>${idx}</td><td>${o.name}</td><td>${o.age}</td><td>${o.score}</td></tr>`, '');

The result is not really intended, the output would be more neat if the cells with undefined were empty. || helps to replace undefined with empty strings:

tableBodyElement.innerHTML = users.reduce((t, o, idx) =>
t + `<tr><td>${idx}</td><td>${o.name||''}</td><td>${o.age||''}</td><td>${o.score||''}</td></tr>`, '');

Using || we solved one problem but created a new problem — score value 0 has disappeared. || cannot be used with variables that can have falsy values 0 or false. An empty string is also falsy, but unless you want to discriminate empty strings from undefined, it is not a problem to replace an empty string with another empty string.

To display 0 we have to replace || by a more complicated conditional statement. I inline the condition using the conditional ternary operator ? ::

tableBodyElement.innerHTML = users.reduce((t, o, idx) =>
t + `<tr><td>${idx}</td><td>${o.name || ''}</td><td>${o.age || ''}</td><td>${o.score===undefined?'':o.score}</td></tr>`, '');

Now the result is accurate:

But there is a better solution — nullish coalescing operator ??, the operator specifically designed to detect null or undefined.

??

Nullish coalescing operator works like || but is more selective.

value1 ?? value2 results in value2 when value1 is undefined or equals null, otherwise value1 is returned.

console.log(undefined ?? 'a'); //a
console.log(null ?? 'a'); //a
console.log(0 ?? 1); //0
console.log(false ?? true); //false
console.log('a' ?? 'b'); //a

?? can be replaced by a function with a condition testing value1 equality to undefined or null:

function nullish(value1, value2) {
if (value1 === undefined || value1 === null) return value2;
else return value1;
}
console.log(nullish(undefined ?? 'a')); //a
console.log(nullish(null ?? 'a')); //a
console.log(nullish(0 ?? 1)); //0
console.log(nullish(false ?? true)); //false
console.log(nullish('a' ?? 'b')); //a

The only purpose of the nullish operator is replacing specifically undefined or null, and not any other falsy values, with default values. Let’s incorporate ?? into the code displaying the user data:

document.getElementById('nullish').innerHTML =
users.reduce((t, o, idx) =>
t + `<tr><td>${idx}</td><td>${o.name ?? ''}</td><td>${o.age ?? ''}</td><td>${o.score ?? ''}</td></tr>`, '');

The code is shorter than the previous version and the output is correct:

The complete but short sample code can be downloaded from https://github.com/marianc000/nullishOperator

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Marian Čaikovski

Marian Čaikovski

1.7K Followers

Java, JavaScript and SQL developer. Interested in data collection and visualization. Comment and disagree with my personal notes on tiny problems that I faced.