编辑 引用删除。与问题无关。
问题
为什么它总是(当所有都是真的时候)取最后值?
示例:
f= 1 && 2 && 3 //3
f= 'k' && 'd' && 's' //'s'
P.S。 :我在使用$.callbacks
调查pub / sub时注意到了
答案 0 :(得分:5)
运营商&&
充当 if-statement 。仅当值为假时才会发生短路。否则,它会不断评估报表。
当你写a && b
时,它意味着:a ? b : a
。
同样,a || b
表示:a ? a : b
。
答案 1 :(得分:4)
编辑:作者已经明确澄清了这个问题。
JavaScript逻辑AND运算符返回左操作数(如果它是假的)或者它返回右操作数。 让我们看一下逻辑真理的表格:
A B A && B
true true true
true false false
false true false
false false false
如您所见,如果A为假,我们可以将其退回:
A A && B
false false
false false
如果A不是假,我们可以返回B:
B A && B
true true
false false
这是一个次要优化,当与弱类型一起使用时会产生有趣的副作用,例如内联if:
var result = callback && callback()
// Generally equivalent to a simple if:
if (callback)
result = callback();
else
result = null;
还使用默认选项:
name = name || 'John';
// Generally equivalent to a simple if:
if (!name)
name = 'John';
至于它为什么会发生,好吧,因为这些运算符是defined like that in ECMA-262。
答案 2 :(得分:3)
那么为什么它总是(当所有都是真的时候)取最后一个值?
因为如果前导值是真的,它不能短路,因为它是一个“AND”运算符,并且所有操作数都必须是真实的以满足条件。
重新评论以下内容:
是的但是为什么它会返回最后一个值?
因为它很有用。 :-)在来自Netscape的第一版的JavaScript中,如果整体表达式为真,则返回true
,如果没有,则返回false
,但几乎立即就知道它是如果它返回最后的操作数,则更有用。
例如,你可以这样做:
var value = obj && obj.value;
...将value
设置为假值(如果obj
为假)或obj.value
(如果obj
不为假)。重要的是,如果obj
为假,则不会抛出错误。如果您不确定obj
已设置,则非常方便防范。您不必停在一个级别,也可以:
var value = obj && obj.sub && obj.sub.value;
如果value
和obj.sub.value
都是真实的,那么 obj
将是假的,或obj.sub
的值(例如,因为我们似乎将它们用作对象,它们是对象实例,而不是null
或undefined
)。
||
做同样的事情:它返回第一个 truthy操作数。
答案 3 :(得分:1)
&&
是logical operator。这会测试值是否为truthy or falsy。这篇链接文章解释了假值等于undefined
,null
,NaN
,0
,""
和false
。
从左到右检查逻辑表达式。如果表达式的任何部分被评估为假,则不会评估表达式的其余部分。在您的示例中,值始终是真实的。在这里,我们可以分解你的第一个表达:
f = 1 && 2 && 3;
f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 3 /* Still truthy, we've reached the end of the expression, f = 3. */
如果3之前的任何值都是假的,表达式就会结束。要显示此操作,只需将您的变量重新声明为:
f = 1 && 2 && 0 && 3;
这里0是假值(如上所述)。这里表达式的执行将以0结束:
f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 0 /* Hey, this is falsy, lets stop here, f = 0. */
f = 3 /* We never get here as the expression has ended */
此处f
最终为0。
在jQuery.Topic()
示例中,&&
用于确保id
确实存在:
topic = id && topics[id]
我们可以用同样的方式解决这个问题:
/* Assume this is your topics array: */
topics = ["", "My First Topic", "My Second Topic"];
/* If we pass in the value 1 as "jQuery.Topic(1)": */
topic = id && topics[id]
topic = 1 /* This is truthy, let's continue... */
topic = topics[1] /* topics[1] === "My First Topic" */
/* Now lets assume we pass in nothing as "jQuery.Topic()": */
topic = id && topics[id]
topic = null /* This is falsy, let's stop here, topic = null. */
以下if
语句仅在topic
真实时才有效。在第一个示例中,情况是这样的,因为topic
的值设置为非空的字符串。在第二个示例中,topic
为null,这是假的。
答案 4 :(得分:1)
因为如果第一个是真的,那么它应该继续并检查第二个操作数直到最后一个。如果你选择1 || 2 || 3而不是它将返回1.
答案 5 :(得分:1)
ECMAScript标准声明12.11.2 Runtime Semantics: Evaluation:
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
1. Let lref be the result of evaluating LogicalANDExpression.
2. Let lval be GetValue(lref).
3. Let lbool be ToBoolean(lval).
4. ReturnIfAbrupt(lbool).
5. If lbool is false, return lval.
6. Let rref be the result of evaluating BitwiseORExpression.
7. Return GetValue(rref).
也就是说,首先我们检查第一个操作数是否被评估为“虚假”值(null
,false
,0
)。如果是,则返回第一个操作数。
但是,如果它是“thruthy”,则对第二个操作数重复相同的过程,如果将其评估为truthy值,则返回原始值(7. Return GetValue(rref)
)。
答案 6 :(得分:0)
短路评估并返回第二个表达式而不是bool是非常有用的功能。
&&
运算符计算左操作数,如果它是真实的,则计算右操作数。类似地,||
运算符计算左操作数,如果它是falsy则计算右操作数。
这允许写出像
这样的东西draw_element(color || "#F00");
具有使用color
的含义,除非未指定(例如color
为null
,undefined
或""
),在这种情况下为默认值使用了价值。
您甚至可以使用
之类的内容draw_element(color || pick_new_color());
只有在未指定颜色时才会调用函数pick_new_color()
。
&&
的一个非常常见的用法是避免错误,例如:
if (x && x.constructor == Array) {
...
}
因为如果x
为null
或undefined
,则无法访问属性(如果您尝试,则会引发异常)。 &&
返回第一个结果falsy
而非false
的事实确实不那么有用。你的代码示例可以做到这一点,但这不是你在Javascript程序中经常找到的东西。
回顾一下:&&
和||
是短路的(即如果在评估第一个操作数后,它们甚至不评估第二个操作数),这非常有用。它们也会返回falsy / truthy值本身而不是bool,这对||
非常有用(对&&
来说没那么有用)。