Javascript 为什么下面的说法是正确的;狗";==(“猫”、“狗”)
为什么Javascript 为什么下面的说法是正确的;狗";==(“猫”、“狗”),javascript,Javascript,为什么&&运算符返回最后一个值(如果该语句为true) 为什么&&运算符返回最后一个值 因为它就是这样做的。在其他语言中,&运算符返回布尔值true或false。在Javascript中,它返回第一个或第二个操作数,因为这些值本身已经是“truthy”或“false” 因此,'Cat'和&&Dog'产生值'Dog',该值等于'Dog' 如果可以将expr1转换为false,则返回expr1;否则,返回expr2。因此,当与布尔值一起使用时,&&如果两者都使用,则返回true 操作数为真;否则,
&&
运算符返回最后一个值(如果该语句为true)
为什么&&运算符返回最后一个值
因为它就是这样做的。在其他语言中,&
运算符返回布尔值true
或false
。在Javascript中,它返回第一个或第二个操作数,因为这些值本身已经是“truthy”或“false”
因此,'Cat'和&&Dog'
产生值'Dog'
,该值等于'Dog'
如果可以将expr1转换为false,则返回expr1;否则,返回expr2。因此,当与布尔值一起使用时,&&如果两者都使用,则返回true
操作数为真;否则,返回false
对于表达式
“Cat”和“Dog”
,第一个表达式“Cat”
不能转换为false或布尔值,因此它返回“Dog”
,因为您询问了true==(true和true)
。如果在布尔操作中使用非布尔值,javascript将转换为布尔值。非空字符串为“true”,因此它返回correct 我猜语言设计者希望使用户能够使用| |运算符作为“合并”运算符,例如“空合并”运算符??在C#中
换句话说,如果需要默认值,可以使用以下习惯用法:
var x = input || "default";
//x will be equal to input, unless input is falsey,
//then x will be equal to "default"
这样想(基于来自
现在您可以看到ToBool(“Cat”)
是true
,因此&
将给出rhs
,它是“Dog”
,然后==
正在执行“Dog”==“Dog”
,这意味着行给出true
为完整起见,
|
运算符可以看作
// pseudo-JavaScript
function ||(lhs, rhs) { // lhs || rhs
if (ToBool(lhs)) return lhs;
return rhs;
}
因为这就是规范所说的。JavaScript的逻辑运算符不会将结果强制转换为布尔值。它们只返回一个操作数的值。当使用&&运算符时,必须计算条件的每一侧,因为
Dog
是最后一个条件,并且整个条件为true,因此返回Dog。我知道这个问题非常基本,但为什么要进行向下表决?从这样的规范来看,非空字符串是“true”,我情不自禁地想:“该死,那个实现看起来像个黑客。”。这是合乎逻辑的,不过…@Cerbrus我认为这是相当的天才,而不是黑客。既然已经有了在必要时基本上充当布尔值的值,为什么还要返回布尔值呢?这就允许更简洁的结构有时不会产生任何负面的副作用。@deceze:这正是为什么这样做是合乎逻辑的:PDo你经常以“因为它就是这样做的”?那么,还有什么其他答案呢?:)OP已经正确地识别了它是如何工作的,它是这样工作的,因为规范这么说的。@FrederikWordenskjold:Wild“因为规范上说,&&
操作符就是这样做的。”更好吗?@Cerburs Yeah。这给了它一个实际的意义。否则,至少对我来说,这听起来像是作者故意不具建设性。我认为有一个专门讨论语义的堆栈交换网站。这个书面回答对我来说是非常有建设性的。如果你指的是标题示例,“Dog”==“Cat”&“Dog”)
,它是在比较“Dog”==“Dog”
<代码>(“猫”&“狗”)大致相当于(!!“猫”?“狗”:“猫”)
。唯一涉及的布尔转换是条件,而不是结果。
function ToBool(x) {
if (x !== undefined)
if (x !== null)
if (x !== false)
if (x !== 0)
if (x === x) // not is NaN
if (x !== '')
return true;
return false;
}
// pseudo-JavaScript
function &&(lhs, rhs) { // lhs && rhs
if (ToBool(lhs)) return rhs;
return lhs;
}
// pseudo-JavaScript
function ||(lhs, rhs) { // lhs || rhs
if (ToBool(lhs)) return lhs;
return rhs;
}