JavaScript逻辑赋值运算符是如何工作的?

18

在JavaScript中,如果我们有一些像这样的代码:

var a = "one";
var b = q || a;
alert (b);

逻辑或运算符将a的值赋给b,弹出框中显示"one"。

这是否仅限于赋值操作还是可以在任何地方使用?

空字符串是否与未定义的情况视为相同?

对于AND变量,它是如何工作的?组合它们会怎样?

有什么好的用法示例或不应使用这些习语的情况吗?


1
不要使用它。这是一个愚蠢的语法结构,不直观,并且会使很多人在阅读代码时变慢。 - MK.
6
@MK,不要因为那些(尚未)了解JavaScript的人不熟悉某种常见结构而排除它。 - Matthew Flaschen
@Matthew没有看到那些问题,我投票关闭。 - Incognito
6个回答

27

要使您的q || a计算为aq应该是“falsy”值。您所做的被称为“短路评估”。

回答您的问题:

  1. 逻辑运算符(如 and - &&,or - ||)也可以用于其他情况。更普遍地用于条件语句,如if此处了解更多

  2. 空字符串不被视为undefined。它们都是falsy值。还有一些更多的falsy值。此处了解更多

  3. AND或JavaScript中的&&不是变量。它是一个操作符

  4. 您使用的习惯用法非常常见。

    var x = val || 'default'; //通常是

    var x = val ? val : 'default' //或

    if (val) var x = val; else var x = 'default';


9
在Javascript中,||的工作方式如下:
  1. 如果左操作数求值为true,则返回左操作数
  2. 否则,返回右操作数
&&的工作方式类似。
你可以利用这个方法进行内联存在检查,例如:
var foo = (obj && obj.property)

如果obj已定义且为真,将把foo设置为obj.property

讲解得非常清楚!! - eddy
1
如果左操作数评估为真,则返回左操作数。不,那是错误的。Truthy,而不是'true'。 - T.J. Crowder

1

这种行为与其他脚本语言(如Perl)共享。逻辑或运算符可用作语法简写,用于指定默认值,因为逻辑或运算符在遇到第一个计算结果为true的表达式时停止计算其操作数:“计算第一个操作数,如果该值被解释为非false,则将其分配。否则重复第二个操作数。”

我发现我经常使用此行为来指定函数参数的默认值。例如:

function myFunction(foo, bar) {
    var fooValue = foo || "a";

    // no need to test fooValue -- it's guaranteed to be defined at this point
}

如果foo的值为false(而不是“false”),会怎样? - JVM
这将导致fooValue ==“a”。在布尔上下文中,false,null,undefined,0,NaN和空字符串都被评估为false--请参见https://developer.mozilla.org/en-US/docs/Glossary/Falsy以获取详细信息。 - Kim Burgaard
正确。然后,在需要false作为值的地方,这可能会失败。 - JVM
在这种情况下,您可以检查 foo == null(如果 foo 为 null 或 undefined,则计算为 true)或明确为 foo === undefined,以允许将 falsy 值指定为参数。问题特别是关于带有类似 a || b 的右侧的逻辑赋值,这就是我上面回答的内容。 - Kim Burgaard

1

我不太确定我理解你的问题。您可以在任何可以使用表达式的地方使用表达式,并且对两个表达式使用逻辑运算符会产生一个表达式。

alert(q||a);
alert(true||false);

var x=5;
var y=0;
if (y!=0 && x/y>2) { /*do something*/ }

最后一位很有用。像大多数语言一样,JavaScript“短路”AND和OR。如果AND的第一部分为false,则不会评估第二部分-这将避免除以0。如果OR的第一部分为true,则不会评估第二部分。
但是您可以在任何可以使用表达式的地方使用布尔运算符。

1

Javascript通过真假性来评估逻辑。 值,例如(false,“”,null,undefined0,-0)被评估为逻辑假。

将此与惰性评估相结合,“OR”操作现在从左到右进行评估,并且一旦找到true,就会停止。 由于在您的示例中,真实性不是布尔值,因此返回该值。

在这种情况下:

x = 0; y = 5; alert(y || x)/*returns 5*/;  alert(x || y)/*also returns 5*/;

这也可以是其他对象。

functionThatReturnsTrue() || functionThatDoesSomething();

1

个人认为 - 不要用于布尔类型的赋值。这可能会令人困惑。因为 undefined !== false,即 false 本身是一个值。

例如,如果您只想在该字段被定义时从对象中复制字段值

var bar.value = false;
var foo = true;

var foo = bar.value || foo;  // ==> should be false as bar.value is defined

对于布尔类型的赋值,你应该真正使用

var foo = (bar.value !== undefined) ? bar.value : foo;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接