请考虑以下代码。
console.log("All" && 1); // 1
console.log("All" || 1); // "All"
如您所见,第一个表达式"All" && 1
的计算结果为1
。这肯定不是布尔值(不是true
(。我期望这里更具体地正确。因为我没有强迫结果为String
.
第二个表达式"All" || 1
,求值为All
。这也不是布尔值。
在 C 语言中,这两个表达式的计算结果为1
。当我强制结果转换为字符串时。
#include <stdio.h>
int main() {
printf("%dn", "All" && 1); // 1
printf("%dn", "All" || 1); // 1
return 0;
}
为什么 JavaScript 的行为不同?更具体地说,为什么 JS 返回非布尔值?
C 中的逻辑运算符总是计算为布尔值。在 C 中,int1
表示true
,int0
表示false
。这就是为什么表达式"All" && 1
和"All" || 1
的计算结果为1
的原因。它们在逻辑上都是正确的。为澄清起见,请考虑以下程序。
#include <stdio.h>
int main() {
printf("%dn", 20 && 10); // 1
printf("%dn", 20 || 10); // 1
return 0;
}
在上面的程序中,表达式20 && 10
和20 || 10
的计算结果仍为1
,即使这些表达式中没有1
。这是有道理的,因为这两个表达式在逻辑上都是正确的。因此,它们的评估结果为1
,相当于 JavaScript 中的true
。
如果 JavaScript 的行为方式与 C 语言相同,则表达式"All" && 10
和"All" || 10
的计算结果将计算为布尔值true
。但是,这不是逻辑运算符在 JavaScript 中的行为方式。这并不是说他们是有缺陷的。
JavaScript 中的值具有真实性和虚假性的概念。例如,值true
、"All"
、10
、[10, 20]
、{ foo: 10 }
和x => 2 * x
都是真实的。另一方面,值false
、""
、0
、undefined
和null
是假的。
JavaScript 的逻辑运算符并不总是像 C 那样计算布尔值。相反,他们评估他们的操作数之一。&&
运算符计算其左操作数是否为假数。否则,它将计算为正确的操作数。同样,||
运算符计算其左操作数是否为真。否则,它将计算为正确的操作数。
现在,"All"
的价值是真实的。因此,"All" && 1
计算出正确的操作数(即1
(,而"All" || 1
计算为左操作数(即"All"
(。请注意,1
和"All"
都是真值,这意味着它们等效于 C 中的1
(表示真实性(。
因此,没有。JavaScript 没有问题。
我在这里引用官方文档:- 逻辑和在JS中
一组操作数的逻辑 AND (&&( 运算符(逻辑连词(为真,当且仅当其所有操作数都为真时。它通常与布尔(逻辑(值一起使用。如果是,则返回布尔值。但是,&&运算符实际上返回指定操作数之一的值,因此如果此运算符与非布尔值一起使用,它将返回非布尔值。
让我们举一些例子,
let a = [1,2,3];
console.log( 0 && a.b ); // return 0
console.log( 1 && a.b ); // return a type error.
在第一个控制台中.log当 JavaScript 首先看到0
时,JS 解释器停止并返回第一个值。
发生这种情况是因为当 JS 解释器将第一个值转换为布尔值时,它的计算结果为false
。我们知道这样一个事实,">在任何&&
运算符上,如果false
单个值,它将返回false
。
所以这里的JS解释器试图通过返回之前来节省一些计算能力,而不进行完整的语句计算。这很好。
逻辑或(||(运算符也是如此。