Problem
In Javascript, is there a null coalescing operator?
In C#, for example, I can perform the following:
String someString = null;
var whatIWant = someString ?? "Cookies!";
The conditional operator is the best approximation I can think of for Javascript:
var someString = null;
var whatIWant = someString ? someString : 'Cookies!';
Which, in my opinion, is a little icky. Is it possible for me to perform better?
Asked by Daniel Schaffer
Solution #1
Update
The nullish coalescing operator (??) is now supported in JavaScript. When the left-hand-side operand is null or undefined, it returns the right-hand-side operand; otherwise, it returns the left-hand-side operand.
Old Answer
Before you use anything, make sure it’s compatible.
A logical OR (||) is used as the JavaScript counterpart of the C# null coalescing operator (??):
var whatIWant = someString || "Cookies!";
Although there are several circumstances where the behavior does not match that of C# (as shown below), this is the basic, terse approach of assigning default/alternative values in JavaScript.
If casting the first operand to a Boolean results in false, the assignment will utilise the second operand, regardless of its type. Be wary of the following scenarios:
alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)
This means:
var whatIWant = null || new ShinyObject(); // is a new shiny object
var whatIWant = undefined || "well defined"; // is "well defined"
var whatIWant = 0 || 42; // is 42
var whatIWant = "" || "a million bucks"; // is "a million bucks"
var whatIWant = "false" || "no way"; // is "false"
Answered by 5 revs, 3 users 67%
Solution #2
function coalesce() {
var len = arguments.length;
for (var i=0; i<len; i++) {
if (arguments[i] !== null && arguments[i] !== undefined) {
return arguments[i];
}
}
return null;
}
var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);
// xyz.val now contains 5
This solution works similarly to the SQL coalesce function in that it takes any number of parameters and returns null if none of them are valid. It works similarly to the C#?? operator in that “”, “false”, and “0” are all deemed NOT NULL and hence count as actual values. If you’re coming from a.net background, this will feel the most natural.
Answered by Brent Larsen
Solution #3
Yes, it is on its way. The proposal can be found here, and the status of implementation can be found here.
It appears as follows:
x ?? y
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false
Answered by vaughan
Solution #4
If || were to take the place of C #’s?? You can always write your own code if isn’t good enough in your scenario because it swallows empty strings and zeros:
function $N(value, ifnull) {
if (value === null || value === undefined)
return ifnull;
return value;
}
var whatIWant = $N(someString, 'Cookies!');
Answered by sth
Solution #5
Nobody has mentioned in here the potential for NaN, which–to me–is also a null-ish value. So, I thought I’d add my two-cents.
For the code given:
var a,
b = null,
c = parseInt('Not a number'),
d = 0,
e = '',
f = 1
;
The first non-false value is obtained by using the || operator:
var result = a || b || c || d || e || f; // result === 1
If you use the new ?? (null coalescing) operator, you will get c, which has the value: NaN
vas result = a ?? b ?? c ?? d ?? e ?? f; // result === NaN
I don’t think either of these are correct. In my own little world of coalesce logic, which may differ from your world, I consider undefined, null, and NaN as all being “null-ish”. So, I would expect to get back d (zero) from the coalesce method.
If your brain works like mine and you wish to exclude NaN, try this custom coalesce approach (rather than the one described here):
function coalesce() {
var i, undefined, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg !== null && arg !== undefined
&& (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
return arg;
}
}
return null;
}
You can alternatively use this, as suggested by @impinball, if you want the code to be as short as possible and don’t mind a little lack of clarity. This takes advantage of the fact that NaN and NaN are never equal. You can learn more about it here: Why isn’t NaN the same as NaN?
function coalesce() {
var i, arg;
for( i=0; i < arguments.length; i++ ) {
arg = arguments[i];
if( arg != null && arg === arg ) { //arg === arg is false for NaN
return arg;
}
}
return null;
}
Answered by Kevin Nelson
Post is based on https://stackoverflow.com/questions/476436/is-there-a-null-coalescing-operator-in-javascript