console.log("" && "Dog"); // ""
console.log("Cat" && "Dog"); // "Dog"
我了解到,除了0
、false
、null
、undefined
、""
和NaN
之外,在像上面那样的逻辑表达式中,其他所有东西都被评估为布尔值true。但为什么输出是第二个字符串而不是第一个?为什么输出不只是“true”,因为它被评估为布尔表达式?
console.log("" && "Dog"); // ""
console.log("Cat" && "Dog"); // "Dog"
我了解到,除了0
、false
、null
、undefined
、""
和NaN
之外,在像上面那样的逻辑表达式中,其他所有东西都被评估为布尔值true。但为什么输出是第二个字符串而不是第一个?为什么输出不只是“true”,因为它被评估为布尔表达式?
在表达式中
"Cat" && "Dog"
// => "Dog"
因为你使用了&&
,JavaScript会确保表达式两侧都是true
。在这种情况下,"Dog"
只是最后一个被评估的东西。var c = "Cat" != null && "Dog" != null
虽然有点冗长,但这归结为
var c = true && true
console.log(c)
// => true
如果您想要一个布尔值的简单快捷方式,请使用 Boolean
构造函数 -
var c = Boolean("Cat" && "Dog")
console.log(c)
// => true
如果你只使用简单的REPL或JavaScript控制台,你可以非常容易地看到此输出。
根据下面的评论之一
使用||
,JavaScript向您承诺至少一个方向是true
。因为"Cat"为真,所以它停在那里并返回"Cat"。这被称为短路评估
我认为这是由于逻辑运算符 && 的本质。Javascript以以下方式执行表达式 "cat" && "Dog"
:
检查值 "cat" - 它返回的不是 ""、0、null、undefined 或 false,而是真值(truthy)。Javascript看到了 &&
,因此它继续执行表达式并遇到字符串 "Dog",它不是 ""、0、null、undefined 或 false 中的任何一个,因此也是真值(truthy),表达式结束并返回它检查的最后一个值。
如果你用 ||
替换 &&
,表达式将在第一个真值处结束,就像这样。
var boolean = "cat" || "dog"
返回第一个值:cat
@naomik的答案已经涵盖了大部分内容。如果您想深入了解,我建议查看ECMAScript规范的第11.11节:
http://www.ecma-international.org/ecma-262/5.1/#sec-11.11
在“Semantics”部分,我们可以看到:
表达式LogicalANDExpression:LogicalANDExpression&&BitwiseORExpression的结果如下所示:
- 令lref为计算LogicalANDExpression的结果。
- 令lval为GetValue(lref)的结果。
- 如果ToBoolean(lval)返回false,则返回lval。
- 令rref为计算BitwiseORExpression的结果。
- 返回GetValue(rref)的结果。
由于逻辑运算的特性,如果你需要测试两个条件是否都成立,而你已经知道第一个条件成立,那么整个测试的结果完全依赖于第二个条件。
true && someValue 等价于 someValue
因此,运算符 && 可以通过返回它的操作数而不是 true/false 值来处理,只需测试第一个操作数而不是第二个操作数。
a && b:
如果 a 的值为 false,则无需继续测试,直接返回 a(因为它是 false)
否则,如果 a 的值为 true,则结果完全取决于 b,所以只需返回 b(无需测试 b 的值为 true 还是 false,直接返回即可)
代码中的实现如下:
function and(a,b) {
if(!a) return a;
return b;
}
同样,运算符||可以被定义为
function or(a,b) {
if(a) return a;
return b;
}
返回操作数而不是true/false有一些优点:
需要较少的评估(请注意,在两种情况下都不会评估b)
不需要定义true/false,因此可以更广泛地使用,甚至跨语言或如果“true”的值更改
可以“黑客”使用,无需if,做像string1 && string2这样有用的含义:“如果string1不为空,则使用string2,否则保持为空(用文本“word”替换字符串的每个单词:aString.split(" ").map(function(word) {return word && "word"});
JavaScript程序员喜欢这种东西(利用一个运算符的副作用来获得不同的、意想不到的行为),他们这样做是为了在聚会上展示语言知识。:D
你可以更简单地实现:
为了验证字符串是否为空,你也可以在Javascript中使用!运算符。
let a = '';
console.log(!a); // => true
a = 'foo';
console.log(!a) // => false
console.log(!!'' && !!'Dog'); // => false
console.log(!!'Cat' && !!'Dog'); // => true
你也可以看看这篇文章:JavaScript 中的双重否定(!!)有什么用途?