【问题标题】:Using the || (or operator) outside of if statements [duplicate]使用 || (或运算符)在 if 语句之外 [重复]
【发布时间】:2015-08-01 19:57:23
【问题描述】:

所以我正在阅读Airbnb's JS styleguide,但我不明白 OR 运算符在以下示例中在做什么。更具体地说,在 Jedy 构造函数中 options || (options = {}); 如果没有将参数传递给构造函数,则基本上是在创建一个空对象?因此,Jedi 构造函数的name 属性将设置为'no name'?

function Jedi(options) {
    options || (options = {});
    this.name = options.name || 'no name';
}

Jedi.prototype.getName = function getName() {
    return this.name;
};

Jedi.prototype.toString = function toString() {
    return 'Jedi - ' + this.getName();
};

附言。似乎有很多用 JS 做事的速记方法。是否有任何好的资源或文章来解释这些是什么以及何时最好使用它们?

【问题讨论】:

  • 这是惯用的 JS;它在这里的使用与if 语句中的用法完全相同——它只是一个表达式,并且由于短路,您的假设是正确的。
  • iirc,airbnb 风格指南还建议使用function Jedi (options = {}) {… 而不是上面的内容(对于 es6)。
  • @DaveNewton:我习惯的模式是options = options || {};。另一个是罕见而奇怪的(尽管我很快就明白了它的意思):-)
  • @Bergi 哦,是的,我指的是第二个,名字之一——我的错。

标签: javascript


【解决方案1】:

|| 运算符有两个参数。如果第一个参数是“真实”值,则返回第一个参数;否则,它返回第二个。它也会短路;也就是说,如果第一个参数是真的,它不会评估第二个。如果第二个参数是一个有副作用的表达式,这可能非常重要。

声明options || (options = {}); 依赖于此。如果options 为真,则不会计算赋值表达式。如果它是假的,那么将评估第二个表达式。

现在,这在功能上等同于声明 options = options || {};。从理论上讲,该语句可能会稍微慢一些,因为它会将options 分配给自己,而不是简单地不分配任何东西。但是,这种影响可以忽略不计。

【讨论】:

  • 这就是看起来令人困惑的事情。您如何在语句中间而不是开头进行变量赋值。这就是(options = {}) 被括号括起来的原因吗?
  • @diegohernandez,赋值是一个表达式,它返回赋值。这里没什么特别的。
  • 第二个版本应该一点也不慢。优化器应该足够聪明才能弄清楚。
【解决方案2】:

Js 逻辑运算符返回的不是 true 或 false,而是 true 或 false 值本身。例如在表达式 x && y 中,如果 x 为假,则返回,否则返回 y。所以算子的真值表是正确的。

|| 也一样。这是指定函数默认值的好方法。

【讨论】:

    【解决方案3】:

    您经常会在 JavaScript 插件中找到此代码,这基本上意味着如果具有名称选项的对象不存在,则创建一个新的对象

    如果您尝试通过以下选项访问属性 options.name 和 options 不存在,那么它会给你一个选项未定义的错误。但是有了这个选项 || (options = {}) 代码,您始终可以确保您正在访问的 JavaScript 对象始终存在。 我会检查是否可以为您提供一些阅读链接。

    这是一个很好的支持链接 How can I create an empty namespace object without overwriting another object with the same name?

    【讨论】:

      【解决方案4】:

      似乎这是一种更简洁的方法来检查对象是否存在,如果不存在,则为其分配一个空对象的值。不过还不是很清楚。更清晰的实现将是

      var options = options || {};
      

      更好,使用es2015默认参数

      function Jedi(options = {}) {
          this.name = options.name || 'no name';
      }
      

      【讨论】:

        【解决方案5】:

        在许多(大多数)编程语言中,运行时不必要的执行会被优化掉。 ||binary 运算符在其任一操作数的计算结果为 true 时返回 true。由于两个操作数都是连续计算的,如果第一个计算结果为真,|| 运算符的结果将为真。所以不需要评估第二个操作数。如果第一个返回 false,那么第二个决定 || 运算符的结果将是什么。这是这里被利用的行为。

        如果选项设置为非空值,它将评估为真。所以不要执行将其初始化为空对象的第二个操作数。在下一行,如果 options.name 不为 null,则将其初始化为 'no name'

        【讨论】:

          猜你喜欢
          • 2014-09-23
          • 2013-05-17
          • 2013-04-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多