相关内容JavaScript中是否存在“空合并”操作符?JavaScript现在有一个??我看到使用更频繁的运算符。以前大多数JavaScript代码使用||。
let userAge = null
// These values will be the same.
let age1 = userAge || 21
let age2 = userAge ?? 21
在什么情况下会??||表现不同?
相关内容JavaScript中是否存在“空合并”操作符?JavaScript现在有一个??我看到使用更频繁的运算符。以前大多数JavaScript代码使用||。
let userAge = null
// These values will be the same.
let age1 = userAge || 21
let age2 = userAge ?? 21
在什么情况下会??||表现不同?
当前回答
作为一个非常简短的规则,你可以用相反的方式来看待它:
|| (or)返回第一个“真值”(如果不存在“真值”则返回最后一个值) ?? (null coalescing)返回第一个“定义”值(如果不存在“定义”值,则返回最后一个值)
例子
x = false || true; // --> true (the first 'truthy' value - parameter 2)
x = false ?? true; // --> false (the first 'defined' value - parameter 1)
其他回答
OR运算符||如果左为假则使用右值,而空合并运算符??如果左为空或未定义,则使用右值。
如果缺少第一个操作符,这些操作符通常用于提供默认值。
但如果你的左值可能包含""或0或false(因为这些是假值),则OR运算符||可能会有问题:
console.log(12 || "not found") // 12
console.log(0 || "not found") // "not found"
console.log("jane" || "not found") // "jane"
console.log("" || "not found") // "not found"
console.log(true || "not found") // true
console.log(false || "not found") // "not found"
console.log(undefined || "not found") // "not found"
console.log(null || "not found") // "not found"
在许多情况下,如果左为null或未定义,您可能只需要右值。这就是空合并运算符??是:
console.log(12 ?? "not found") // 12
console.log(0 ?? "not found") // 0
console.log("jane" ?? "not found") // "jane"
console.log("" ?? "not found") // ""
console.log(true ?? "not found") // true
console.log(false ?? "not found") // false
console.log(undefined ?? "not found") // "not found"
console.log(null ?? "not found") // "not found"
而??operator在当前的LTS版本的Node (v10和v12)中不可用,你可以在某些版本的TypeScript或Node中使用它:
的? ?operator在2019年11月被添加到TypeScript 3.7中。
最近,??operator被包含在ES2020中,由Node 14(2020年4月发布)支持。
当空合并运算符??是支持的,我通常使用它而不是OR运算符||(除非有很好的理由不这样做)。
函数f(输入){ Const val = input || 1; 返回41 + val; } 函数g(输入){ val = input ??1; 返回41 + val; } Console.log ("using ||:", f(0)); console.log(“使用? ?:“g (0));
null(ish)合并运算符只适用于null和undefined。所以,当你不想要这些值,但你将接受其他假值时,使用null(ish)合并运算符:
console.log(空? ?“nullish”); console.log(未定义? ?“nullish”); console.log ("" ??“nullish”); console.log (0 ??“nullish”); console.log(假的? ?“nullish”);
逻辑上的“或”将跳过任何错误的值,并给出另一个值。 逻辑或将跳过任何错误的值,并给出另一个参数。这是有效的,现在是惯用的,但它并不总是你想要的:
console.log(null ||“假”); 控制台.log(未定义||“假”); console.log(“” || ”假“); 控制台.log(0 ||“假”); console.log(false ||“假”);
这里有一些关于如何决定你需要哪一个的规则。最简单的测试:
你只是想防止空(和未定义-它通常是一样的事情)?然后使用??如果您不确定,那么默认使用空合并操作符可能是个好主意。 你知道你也不想要0或""吗?然后使用||。
第二个问题实际上很棘手。您如何知道需要丢弃虚假值呢?好吧,第一个代码片段展示了这样做会发生什么:f(0)将丢弃0,从而产生不同的结果。这是一种常见的错误来源。由于构造a = b || c通常会引入一个回退值(在本例中是c),它可能会在您无意时意外地返回到它。
function updateAge(years) {
var yearsToAdd = years || 1;
return this.age + yearsToAdd
}
如果您想为调用updateAge()(没有参数)提供一个回退,那么这个方法是可行的,但是如果您调用updateAge(0)(没有更新)则会失败。类似地,你可以有:
function sayMyName(greeting) {
var prefix = greeting || "Hello, my name is ";
return prefix + this.firstName;
}
同样,这适用于sayMyName()(没有参数),但不适用于sayMyName("")(显式地没有问候)。
概括地说,如果您提供的回退值与假值不同,那么您可能会遇到问题。然而,如果你的回退是错误的值- num || 0或str || "",那么这并不重要。
很少(或者应该是)您可能期望一个混合类型(数字、字符串或对象等)并为其提供一个回退:input ||回退是有效的,但将拒绝空字符串和零。它通常是错误的,除非你明确地不想要这些。
简单地说,你应该使用空合并运算符??在任何时候。判断它是否是一个潜在的错误将会减少认知负担。也没有太多理由去避免它。它比布尔OR更新,所以它不能在旧的环境中工作,这是真的,但是现在你应该为那些环境编译你的代码。如果您不能或不愿意这样做,那么您没有选择,应该使用布尔or。
作为一个非常简短的规则,你可以用相反的方式来看待它:
|| (or)返回第一个“真值”(如果不存在“真值”则返回最后一个值) ?? (null coalescing)返回第一个“定义”值(如果不存在“定义”值,则返回最后一个值)
例子
x = false || true; // --> true (the first 'truthy' value - parameter 2)
x = false ?? true; // --> false (the first 'defined' value - parameter 1)
简而言之
空合并运算符??区分:
null值(null, undefined) 虚实但定义的值(false, 0,”等)
||(逻辑或)处理这两个相同。
我创建了一个简单的图形来说明JavaScript中null和falsey值的关系:
进一步的解释:
let x, y
x = 0
y = x || 'default' // y = 'default'
y = x ?? 'default' // y = 0
如上所述,操作符之间的差异??||是一个检查空值,一个检查假值。然而,在许多情况下,它们的行为是相同的。这是因为在JavaScript中,每个空值都是假值(但不是每个假值都是空值)。
利用我们上面学到的知识,我们可以为不同的行为创建一些例子:
let y
y = false || 'default' // y = 'default'
y = false ?? 'default' // y = false
y = 0n || 'default' // y = 'default'
y = 0n ?? 'default' // y = 0n
y = NaN || 'default' // y = 'default'
y = NaN ?? 'default' // y = NaN
y = '' || 'default' // y = 'default'
y = '' ?? 'default' // y = ''
由于新的Nullish Coalescing Operator可以区分无值和假值,因此,如果您需要检查是否没有字符串或空字符串,它将非常有用。一般来说,你可能会使用??而不是||大多数时候。
最后也是最不重要的是,这里有两个例子,它们表现相同:
let y
y = null || 'default' // y = 'default'
y = null ?? 'default' // y = 'default'
y = undefined || 'default' // y = 'default'
y = undefined ?? 'default' // y = 'default'
当||被用作布尔条件时,该值为false。例如:
let userAge = false
// These values will be the same.
let age1 = userAge || 21 // 21
let age2 = userAge ?? 21 // false
逻辑上的OR仍然会为任何不为true的值给出下一个值。在这种情况下,它给出的值是21。在哪里? ?只处理null和undefined。