【问题标题】:Javascript AND operator within assignment赋值中的 Javascript AND 运算符
【发布时间】:2018-05-20 07:49:48
【问题描述】:

我知道在 JavaScript 中你可以做到:

var oneOrTheOther = someOtherVar || "these are not the droids you are looking for...";

如果变量oneOrTheOther 不是nullundefinedfalse,则变量oneOrTheOther 将采用第一个表达式的值。在这种情况下,它被分配给第二条语句的值。

但是,当我们使用逻辑 AND 运算符时,变量 oneOrTheOther 会分配给什么?

var oneOrTheOther = someOtherVar && "some string";

someOtherVar 不为假时会发生什么?
someOtherVar 为假时会发生什么?

刚刚学习 JavaScript,我很好奇将赋值与 AND 运算符结合使用会发生什么。

【问题讨论】:

标签: javascript variable-assignment logical-operators and-operator


【解决方案1】:

基本上,逻辑与运算符 (&&) 如果第一个操作数为 truthy,则返回第二个操作数的值,如果是,则返回第一个操作数的值本身falsy,例如:

true && "foo"; // "foo"
NaN && "anything"; // NaN
0 && "anything";   // 0

请注意,falsy 值是在布尔上下文中使用时强制转换为 false 的值,它们是 nullundefined0NaN,一个空字符串,当然还有false,其他任何东西都会强制转换为true

【讨论】:

  • 嗯,好的。谢谢。这是有道理的,毕竟它与 OR 运算符相反。
  • 因此,当与布尔值一起使用时,如果两个操作数都为真,则 && 返回真;否则,返回 false。 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)
  • 我喜欢这个例子。如果你能包含一些关于 && 被称为“守卫”运算符的信息,这对空值检查很有用,因为这是一个很好的上下文。你甚至可以在这里引用道格拉斯·克罗克福德:javascript.crockford.com/survey.html
【解决方案2】:

&& 有时被称为 guard 运算符。

variable = indicator && value

只有在指标为真时才能设置值。

【讨论】:

  • 非常明确的答案。其他答案让我很困惑,但这是一种非常清晰的表达方式。谢谢!
  • 我认为这个答案显然是错误的。执行上述语句后,'variable' 的值就是表达式“indicator && value”的值,无论它可能是什么。所以赋值左侧的变量值总是设置为某个值。无论右侧发生什么(除非抛出错误)。没有?
【解决方案3】:

初学者示例

如果您尝试访问“user.name”但会发生这种情况:

Uncaught TypeError: Cannot read property 'name' of undefined 

不要害怕。您现在可以在现代浏览器上使用 ES6 可选链。

const username = user?.name;

参见 MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

这里有一些关于守卫运算符的更深入的解释,可能有助于理解。

在引入可选链之前,您可以在赋值中使用 && 运算符 来解决这个问题,或者通常称为 guard 运算符,因为它可以“保护”未定义的错误发生.

这里有一些你可能会觉得奇怪的例子,但请继续阅读,稍后会解释。

var user = undefined;
var username = user && user.username;
// no error, "username" assigned value of "user" which is undefined

user = { username: 'Johnny' };
username = user && user.username;
// no error, "username" assigned 'Johnny'

user = { };
username = user && user.username;
// no error, "username" assigned value of "username" which is undefined

解释:在守卫操作中,每个术语一次从左到右评估一个。如果评估的值是虚假的,则评估停止,然后分配该值。如果到达最后一项,则分配它是否为假。

falsy 表示它是这些值中的任何一个 undefined, false, 0, null, NaN, '' 并且 truthy 只是表示 NOT falsy。

奖励:OR 运算符

实际使用中另一个有用的奇怪赋值是 OR 运算符,它通常用于如下插件:

this.myWidget = this.myWidget || (function() {
   // define widget
})();

如果“this.myWidget”是假的,它只会分配代码部分。这很方便,因为您可以在任何地方多次声明代码,而不用关心它之前是否已分配,知道它只会被分配一次,因为使用插件的人可能会不小心多次声明您的脚本标签 src。

说明:每个值都是从从左到右,一次一个计算的。如果一个值是真值,它会停止评估并分配该值,否则,继续进行,如果到达最后一项,则无论它是否为假,它都会被分配。

额外学分:结合 && 和 ||在作业中

你现在拥有了终极力量,可以做一些非常奇怪的事情,比如在回文中使用它的这个非常奇怪的例子。

function palindrome(s,i) {
 return (i=i || 0) < 0 || i >= s.length >> 1 || s[i] == s[s.length - 1 - i] && isPalindrome(s,++i);
}

在这里深入解释:Palindrome check in Javascript

编码愉快。

【讨论】:

  • 谢谢你,很棒的例子!帮助我理解 && 和 ||运营商! +1
  • 感谢您的回答!我很好奇 JS 会继续尝试访问最深级别的属性多久?例如,如果您正在等待响应到达您的后端,那么使用 var x = y &amp;&amp; y.z 是否安全?
【解决方案4】:

引用Douglas Crockford1

如果第一个操作数是假的,&amp;&amp; 运算符会生成其第一个操作数的值。否则它产生第二个操作数的值。


1 道格拉斯·克罗克福德:JavaScript: The Good Parts - 第 16 页

【讨论】:

【解决方案5】:

根据Annotated ECMAScript 5.1 section 11.11

如果是逻辑或运算符(||),

expr1 || expr2 如果可以转换为 true,则返回 expr1; 否则,返回 expr2。因此,当与布尔值一起使用时,|| 如果任一操作数为真,则返回真;如果两者都为假,则返回 假的。

在给定的示例中,

var oneOrTheOther = someOtherVar || “这些不是你要找的机器人……继续前进”;

如果 Boolean(someOtherVar) 为真,结果将是 someOtherVar 的值。(请参考。Truthiness of an expression)。如果它是假的,结果将是“这些不是你正在寻找的机器人......继续前进”;

如果是逻辑与运算符(&&),

如果可以转换为false则返回expr1;否则,返回 expr2.因此,当与布尔值一起使用时,&& 如果两者都返回 true 操作数为真;否则,返回 false。

在给定的示例中,

案例一:当 Boolean(someOtherVar) 为 false 时:返回 someOtherVar 的值。

案例 2:当 Boolean(someOtherVar) 为真时:它返回“这些不是您要寻找的机器人......继续前进”。

【讨论】:

    【解决方案6】:

    我对此的看法与大多数答案不同,所以我希望这对某人有所帮助。

    要计算涉及|| 的表达式,您可以在找到一个为真词后立即停止计算该表达式。在这种情况下,您拥有两种知识,而不仅仅是一种:

    1. 鉴于术语为真,整个表达式的计算结果为真。
    2. 知道 1,您可以终止评估并返回最后评估的术语。

    例如,false || 5 || "hello" 的计算结果直到包含 5,这是真的,所以这个表达式计算为 true 并返回 5。

    因此,表达式的值是用于 if 语句的值,但最后评估的术语是分配变量时返回的值。

    类似地,使用&amp;&amp; 评估表达式涉及在第一个错误的术语处终止。然后它产生一个值 false 并返回最后一个被评估的术语。 (编辑:实际上,它返回最后一个不虚假的评估项。如果没有,它返回第一个。)

    如果您现在阅读了上述答案中的所有示例,那么一切都很有意义:)

    (这只是我对此事的看法,以及我对其实际运作方式的猜测。但未经证实。)

    【讨论】:

      【解决方案7】:

      我在工作中看到 && 在这里过度使用赋值语句。担忧是双重的: 1)“指标”检查有时是一个开发人员不考虑开销的函数。 2)开发人员很容易将其视为安全检查,而不是认为他们将 false 分配给他们的 var。我喜欢他们有类型安全的态度,所以我让他们改变这个:

      var currentIndex = App.instance &amp;&amp; App.instance.rightSideView.getFocusItemIndex();

      到这里:

      var currentIndex = App.instance &amp;&amp; App.instance.rightSideView.getFocusItemIndex() || 0;

      所以他们按预期得到一个整数。

      【讨论】:

        猜你喜欢
        • 2014-07-18
        • 1970-01-01
        • 2010-12-17
        • 2021-09-09
        • 1970-01-01
        • 2011-07-02
        • 2011-08-02
        • 2019-10-06
        相关资源
        最近更新 更多