JavaScript 中是否有 “空合并” 运算符?

Javascript 中是否有空合并运算符?

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

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

我可以为 Javascript 找到的最佳近似是使用条件运算符:

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

恕我直言,这有点棘手。我可以做得更好吗?

答案

与 C#空合并运算符( ?? )等效的 JavaScript 使用逻辑 OR( || ):

var whatIWant = someString || "Cookies!";

在某些情况下(如下所述),该行为与 C#的行为不匹配,但这是在 JavaScript 中分配默认 / 替代值的通用,简洁的方法。


澄清度

无论第一个操作数的类型如何,如果将其强制转换为 Boolean 都将导致false ,则赋值将使用第二个操作数。当心以下所有情况:

alert(Boolean(null)); // false
alert(Boolean(undefined)); // false
alert(Boolean(0)); // false
alert(Boolean("")); // false
alert(Boolean("false")); // true -- gotcha! :)

这表示:

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"
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

此解决方案的工作方式类似于 SQL 合并函数,它接受任意数量的参数,如果它们都不具有值,则返回 null。它的行为类似于 C#?从 “”,“ false” 和 “0” 被视为 NOT NULL 的意义上讲,因此算作实际值。如果您来自. net 背景,这将是最自然的解决方案。

是的,它即将推出。请参阅此处的提案此处的 实施状态

看起来像这样:

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

如果||代替 C#的??在您的情况下还不够好,因为它会吞下空字符串和零,因此您始终可以编写自己的函数:

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

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

这里没有人提到NaN的潜力,对我而言, NaN也是零价值。所以,我以为我要加两分钱。

对于给定的代码:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

如果要使用||运算符,您将获得第一个非 false 值:

var result = a || b || c || d || e || f; // result === 1

如果您使用典型的合并方法( 如此处所述) ,则将得到c ,其值为: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

这些对我来说都不对。在我自己的合并逻辑小世界中(可能与您的世界不同),我认为未定义,空值和 NaN 都是 “空值的”。因此,我希望从合并方法中得到d (零)。

如果任何人的大脑像我的大脑一样工作,并且您想排除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;
}

对于那些想要代码尽可能短并且不介意不够清晰的人,您也可以按照 @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;
}

目前尚不支持,但是 JS 标准化过程正在其上进行: https : //github.com/tc39/proposal-optional-chaining

当心 JavaScript 的 null 定义。在 javascript 中,“no value” 有两个定义。 1. Null:当变量为 null 时,表示它不包含任何数据,但是该变量已在代码中定义。像这样:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

在这种情况下,变量的类型实际上是对象。测试一下。

window.alert(typeof myEmptyValue); // prints Object
  1. 未定义:如果之前未在代码中定义变量,并且不出所料,则该变量不包含任何值。像这样:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts

在这种情况下,变量的类型为 “未定义”。

请注意,如果您使用类型转换比较运算符(==),则 JavaScript 将对这两个空值均起同样的作用。为了区分它们,请始终使用类型严格的比较运算符(===)。

阅读您的说明后,@ Ates Goral 的答案提供了如何在 JavaScript 中使用 C#执行相同的操作。

@Gumbo 的答案提供了检查 null 的最佳方法;但是,请务必注意 JavaScript 中=====的区别, 特别是在涉及检查undefined和 / 或null

有关于两个词的区别一个真正的好文章在这里 。基本上,请理解,如果使用==而不是=== ,JavaScript 将尝试合并您正在比较的值,并合并返回比较的结果。

请注意,React 的create-react-app工具链自版本 3.3.0(发布于 2019 年 12 月 5 日)以来支持空合并。从发行说明中:

可选链接和空位合并运算符

现在,我们支持可选的链接和无效合并运算符!

// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined

// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false

这就是说,如果您使用create-react-app 3.3.0+,则可以立即在 React 应用程序中使用 null-coalesce 运算符。

JS 现在得到一个空合并运算符!是的,目前正在第三阶段进入第四阶段。 https://github.com/tc39/proposal-nullish-coalescing

提案中的示例:

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