在JavaScript中有“空合并”操作符吗?

时间:2022-01-22 11:46:46

Is there a null coalescing operator in Javascript?

Javascript中是否存在空合并操作符?

For example, in C#, I can do this:

例如,在c#中,我可以这样做:

String someString = null;
var whatIWant = someString ?? "Cookies!";

The best approximation I can figure out for Javascript is using the conditional operator:

对于Javascript,我能算出的最佳近似是使用条件运算符:

var someString = null;
var whatIWant = someString ? someString : 'Cookies!';

Which is sorta icky IMHO. Can I do better?

那是sorta icky IMHO。我能做得更好吗?

8 个解决方案

#1


1533  

The JavaScript equivalent of the C# null coalescing operator (??) is using a logical OR (||):

与c#空合并操作符(?)等价的JavaScript使用逻辑或(||):

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.

有一些案例(澄清如下):行为与c#不匹配,但这是在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


55  

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.

该解决方案与SQL coalesce函数类似,它接受任意数量的参数,如果其中没有一个参数具有值,则返回null。它的行为就像c# ?在“”、false和0被认为不是NULL的意义上的运算符,因此被算作实际值。如果你来自。net背景,这将是最自然的感觉解决方案。

#3


38  

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:

如果||作为c#的替代品??在你的例子中还不够好,因为它包含了空字符串和零,所以你总是可以写出你自己的函数:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

#4


10  

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.

这里没有人提到NaN的潜力,对我来说,它也是一个零值。所以,我想我应该加上2分。

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

如果您使用的是典型的合并方法,如本文所示,您将得到c,它具有值: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.

我觉得这两种都不对。在我自己的合并逻辑的小世界里,它可能与你们的世界不同,我认为无定义的、零的和NaN都是“零”的。因此,我期望从合并方法中返回d(0)。

If anyone's brain works like mine, and you want to exclude NaN, then this method will accomplish that:

如果任何人的大脑像我的一样工作,并且你想要排除NaN,那么这个方法将完成这个:

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?

对于那些希望代码尽可能短,并且不介意有一点不清晰的人,您也可以使用@impinball建议的这一方法。这充分利用了NaN从不等于NaN这一事实。你可以在这里读到更多:为什么NaN不等于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;
}

#5


6  

Currently no support, but the JS-standardization process is working on it: https://github.com/tc39/proposal-optional-chaining

目前还没有支持,但是jms标准化过程正在进行:https://github.com/tc39/sal-optional -chaining

#6


4  

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:

注意JavaScript特定的null定义。javascript中“无值”有两个定义。1。Null:当一个变量为Null时,它表示其中不包含任何数据,但是在代码中已经定义了这个变量。是这样的:

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
  1. 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'.

如果是这种情况,则变量的类型为“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 (===).

注意,如果使用类型转换比较运算符(==),JavaScript将对这两种空值执行同样的操作。为了区分它们,总是使用类型严格的比较运算符(==)。

#7


3  

After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.

在阅读您的说明之后,@Ates Goral的回答提供了如何在c#中使用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.

@Gumbo的答案提供了检查null的最佳方法;但是,要注意在JavaScript中==与=== =之间的差异,特别是在检查未定义和/或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.

这里有一篇很好的文章关于两项的区别。基本上,如果您使用==而不是=== =,JavaScript将尝试合并正在比较的值,并在合并之后返回比较的结果。

#8


2  

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

#1


1533  

The JavaScript equivalent of the C# null coalescing operator (??) is using a logical OR (||):

与c#空合并操作符(?)等价的JavaScript使用逻辑或(||):

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.

有一些案例(澄清如下):行为与c#不匹配,但这是在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


55  

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.

该解决方案与SQL coalesce函数类似,它接受任意数量的参数,如果其中没有一个参数具有值,则返回null。它的行为就像c# ?在“”、false和0被认为不是NULL的意义上的运算符,因此被算作实际值。如果你来自。net背景,这将是最自然的感觉解决方案。

#3


38  

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:

如果||作为c#的替代品??在你的例子中还不够好,因为它包含了空字符串和零,所以你总是可以写出你自己的函数:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

#4


10  

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.

这里没有人提到NaN的潜力,对我来说,它也是一个零值。所以,我想我应该加上2分。

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

如果您使用的是典型的合并方法,如本文所示,您将得到c,它具有值: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.

我觉得这两种都不对。在我自己的合并逻辑的小世界里,它可能与你们的世界不同,我认为无定义的、零的和NaN都是“零”的。因此,我期望从合并方法中返回d(0)。

If anyone's brain works like mine, and you want to exclude NaN, then this method will accomplish that:

如果任何人的大脑像我的一样工作,并且你想要排除NaN,那么这个方法将完成这个:

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?

对于那些希望代码尽可能短,并且不介意有一点不清晰的人,您也可以使用@impinball建议的这一方法。这充分利用了NaN从不等于NaN这一事实。你可以在这里读到更多:为什么NaN不等于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;
}

#5


6  

Currently no support, but the JS-standardization process is working on it: https://github.com/tc39/proposal-optional-chaining

目前还没有支持,但是jms标准化过程正在进行:https://github.com/tc39/sal-optional -chaining

#6


4  

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:

注意JavaScript特定的null定义。javascript中“无值”有两个定义。1。Null:当一个变量为Null时,它表示其中不包含任何数据,但是在代码中已经定义了这个变量。是这样的:

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
  1. 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'.

如果是这种情况,则变量的类型为“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 (===).

注意,如果使用类型转换比较运算符(==),JavaScript将对这两种空值执行同样的操作。为了区分它们,总是使用类型严格的比较运算符(==)。

#7


3  

After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.

在阅读您的说明之后,@Ates Goral的回答提供了如何在c#中使用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.

@Gumbo的答案提供了检查null的最佳方法;但是,要注意在JavaScript中==与=== =之间的差异,特别是在检查未定义和/或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.

这里有一篇很好的文章关于两项的区别。基本上,如果您使用==而不是=== =,JavaScript将尝试合并正在比较的值,并在合并之后返回比较的结果。

#8


2  

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