【问题标题】:Javascript && operator - clarification? [duplicate]Javascript && 运算符 - 澄清? [复制]
【发布时间】:2013-10-07 08:01:39
【问题描述】:

编辑: 报价已删除。与问题无关。

问题

为什么它总是(当一切都是真实的)取 last 值?

例子:

f= 1 && 2 && 3 //3

f= 'k' && 'd' && 's' //'s'

附言:我注意到在使用$.callbacks调查发布/订阅时@

【问题讨论】:

  • && 运算符应该与布尔操作数一起使用。但是由于 javascript 允许编写这种弱类型的色情内容,结果令人惊讶:-)
  • 这是为了执行的性能,因为 AND 是在所有条件都正确时返回 true。当第一个失败时,它将停止检查,因为当其中任何一个为假时,条件将返回假。所以下一个就不用检查了。

标签: javascript jquery


【解决方案1】:

运算符&& 充当if 语句。仅当值 为假 时才会发生短路。否则,它会继续评估语句。

当您写a && b 时,它的意思是:a ? b : a。 同样,a || b 表示:a ? a : b

【讨论】:

  • 更深入地查看您的答案 - 它实际上回答了我的问题。因为这就像一个链条。如果A 然后B 和(同一轮)如果B 然后C - 这意味着我留下C
  • || 被广泛用于为变量分配默认值,如下所示:如果用户没有提供值,setting = setting || false 将分配 false(即undefined
【解决方案2】:

编辑:作者已经明确地澄清了这个问题。

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

这是一个小的优化,当与弱类型一起使用时会导致有趣的副作用,例如 inline 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

【讨论】:

  • 问题是关于返回最后一个值
  • @RoyiNamir,我现在更新了答案。
【解决方案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 的值,如果 objobj.sub 都是真的(例如,因为我们似乎将它们用作对象,它们是对象实例而不是 @ 987654336@ 或 undefined)。

|| 做同样的事情:它返回它的第一个真值操作数。

更多:JavaScript's Curiously Powerful OR Operator (||)

【讨论】:

  • 是的,但为什么它返回最后一个值?
  • @RoyiNamir:抱歉,更新了。 :-)
  • @Denis:啊,是的,我将语句分组不正确,谢谢。
【解决方案4】:

因为如果第一个是真的,那么它应该继续检查第二个操作数直到最后一个。如果你愿意选择 1 || 2 || 3 相反,它将返回 1。

【讨论】:

【解决方案5】:

&& 是一个logical operator。这将测试一个值是否为truthy or falsy。这篇链接文章解释了虚假值等于undefinednullNaN0""false

从左到右检查逻辑表达式。如果表达式的任何部分被评估为 falsy,则表达式的其余部分将不被评估。在您的示例中,该值始终是真实的。在这里,我们可以分解您的第一个表达式:

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,这是假的。

【讨论】:

  • 这是一个表达式,而不是一个语句。而且它也不需要多个操作数,它只是多个 && 表达式:1 && (2 && (0 && 3))
【解决方案6】:

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).

也就是说,首先我们检查第一个操作数是否被评估为“假”值(nullfalse0)。如果是,则返回第一个操作数。

但是,如果它是“真值”,则对第二个操作数重复相同的过程,如果它被评估为真值,则返回原始值 (7. Return GetValue(rref))。

【讨论】:

    【解决方案7】:

    短路评估和返回第二个表达式而不是布尔值是非常有用的功能。

    && 运算符计算左操作数,如果为真则计算右操作数。类似地,|| 运算符计算左操作数,如果它是假的,则计算右操作数。

    这允许写类似的东西

    draw_element(color || "#F00");
    

    使用color 的含义,除非未指定(例如colornullundefined""),在这种情况下使用默认值。

    你甚至可以使用类似的东西

    draw_element(color || pick_new_color());
    

    只有在没有指定颜色时才会调用函数pick_new_color()

    && 的一个非常常见的用法是避免错误,例如:

    if (x && x.constructor == Array) {
        ...
    }
    

    因为如果xnullundefined 你不能访问属性(如果你尝试会引发异常)。 && 返回第一个结果(如果它是 falsy 而不仅仅是 false)这一事实确实不是那么有用。您的代码示例可以做到这一点,但在 Javascript 程序中并不常见。

    回顾一下:&&|| 是短路的(即,如果在评估第一个操作数后结果已知,它们甚至不评估第二个操作数),这非常有用。它们还返回虚假/真实值本身而不是布尔值,这对|| 非常有用(对&& 没有太大用处)。

    【讨论】:

      猜你喜欢
      • 2017-07-28
      • 2020-07-29
      • 1970-01-01
      • 2015-10-23
      • 2012-11-09
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多