问题
Is there a null coalescing operator in Javascript?
For example, in C#, I can do this:
String someString = null;
var whatIWant = someString ?? \"Cookies!\";
The best approximation I can figure out for Javascript is using the conditional operator:
var someString = null;
var whatIWant = someString ? someString : \'Cookies!\';
Which is sorta icky IMHO. Can I do better?
回答1:
The JavaScript equivalent of the C# null coalescing operator (??
) is using a logical OR (||
):
var whatIWant = someString || "Cookies!";
There are cases (clarified below) that the behaviour won't match that of C#, but this is the general, terse way of assigning default/alternative values in JavaScript.
Clarification
Regardless of the type of the first operand, if casting it to a Boolean results in false
, the assignment will use the second operand. Beware of all the cases below:
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"
回答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 like the SQL coalesce function, it accepts any number of arguments, and returns null if none of them have a value. It behaves like the C# ?? operator in the sense that "", false, and 0 are considered NOT NULL and therefore count as actual values. If you come from a .net background, this will be the most natural feeling solution.
回答3:
If ||
as a replacement of C#'s ??
isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:
function $N(value, ifnull) {
if (value === null || value === undefined)
return ifnull;
return value;
}
var whatIWant = $N(someString, 'Cookies!');
回答4:
Yes, it is coming soon. See proposal here and implementation status here.
It looks like this:
x ?? y
Example
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
回答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 given code:
var a,
b = null,
c = parseInt('Not a number'),
d = 0,
e = '',
f = 1
;
If you were to use the ||
operator, you get the first non-false value:
var result = a || b || c || d || e || f; // result === 1
If you use the typical coalesce method, as posted here, you will get c
, which has the value: NaN
var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'
Neither of these seem right to me. 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 anyone's brain works like mine, and you want to exclude NaN
, then this method will accomplish that:
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;
}
For those who want the code as short as possible, and don't mind a little lack of clarity, you can also use this as suggested by @impinball. This takes advantage of the fact that NaN is never equal to NaN. You can read up more on that here: Why is NaN not equal to 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;
}
回答6:
Currently no support, but the JS-standardization process is working on it: https://github.com/tc39/proposal-optional-chaining
回答7:
beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript. 1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:
var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts
in such case, the type of your variable is actually Object. test it.
window.alert(typeof myEmptyValue); // prints Object
Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:
if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); } // alerts
if such case, the type of your variable is 'undefined'.
notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).
回答8:
After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.
@Gumbo's answer provides the best way to check for null; however, it's important to note the difference in ==
versus ===
in JavaScript especially when it comes to issues of checking for undefined
and/or null
.
There's a really good article about the difference in two terms here. Basically, understand that if you use ==
instead of ===
, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.
回答9:
JS is getting a null coalescing operator now! Currently in Stage-3 moving into Stage-4, yay! https://github.com/tc39/proposal-nullish-coalescing
example in proposal:
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
回答10:
Yes, there is. It is called @babel/plugin-proposal-optional-chaining
See my detailed answer here: https://stackoverflow.com/a/54482814/5506730
来源:https://stackoverflow.com/questions/476436/is-there-a-null-coalescing-operator-in-javascript