【问题标题】:Understanding the "|| {}" construct in javascript [duplicate]理解 javascript 中的“|| {}”结构 [重复]
【发布时间】:2012-08-22 04:38:33
【问题描述】:

可能重复:
What does “var FOO = FOO || {}” mean in Javascript?
Javascript - Can you add condition to variable declaration

我相信这与范围界定有关,而不是重新定义范围。我在流行的 javascript 框架中看到了很多这样的内容:

var something = something || {};

这与不小心重新定义顶级变量有关吗?

【问题讨论】:

    标签: javascript scope redefinition


    【解决方案1】:

    你是对的。如果变量已经存在(我们的或不存在的),请不要更改它。如果它不存在,让我们创建一个新的。

    【讨论】:

    • 使用var关键字,总是会创建一个新对象。
    • @js1568 这似乎合乎逻辑,但事实并非如此。 This demo 为我记录原始对象。基本上这意味着创建一个新变量,但它的值将与旧变量相同。
    • 您的示例对每个语句具有相同的范围,因此您不会更改任何内容。让我展示一下全局变量something 不会受到局部变量something 的影响。表明它们是两个不同的对象,但是在函数执行的开始,它们当然是等价的。
    • @js1568 嗯,是的,但那是它不在全局范围内的时候。大多数库不会像这样检查它们的变量,除非它在全局范围内。不过你是对的。
    【解决方案2】:

    var something = something || {};

    可以在带有可能未设置参数的函数内部使用

        function doStuff( arg1, arg2, arg3 ) {
            arg2 = arg2 || {};
            arg3 = arg3 || arg1 + 2;
        };
    

    这使得调用函数 doStuff 时第二个和第三个参数是可选的

    【讨论】:

      【解决方案3】:

      这将创建一个具有本地范围的新对象。如果外部something 为空、假或未定义(或其他错误),则新变量将为空对象{}

      【讨论】:

      • 不一定是外层;重新声明不是错误,也不会覆盖。 (除非您处于严格模式。)
      • 其实现在再读一遍,完全错了。
      • 我认为我有一个基本假设,即该语句位于函数或闭包中。但我不同意这是完全错误的。例如:jsfiddle.net/3RfYV/1
      • 我知道,这根本不是我的意思。外部something 被忽略,因为它被重新定义为undefined
      【解决方案4】:

      您没有重新定义范围,您只是确保变量存在于现有范围内。赋值语句可以读作:

      "如果something 存在(而不是undefinednull0false,则设置something = something(即,什么都不做)。如果它不存在,则创建它并将其设置为等于空对象字面量"

      【讨论】:

      • @js1568: 不。如果something 已经存在于范围内,var something 不会做任何事情。
      • @FelixKling 在同一范围内是正确的,您(可能)用同一个对象覆盖同一个对象。但是,我们假设这是函数的第一行,这将在不同的范围内。
      • @js1568:当然,用var 声明的变量是本地的,但是没有任何地方说我们在这里讨论的是函数。你为什么这么认为?并且Jack明确提到它确保变量在existing(我将其读为current)范围内的存在。
      • 很公平,我明白你的意思。我在那里过度阅读。
      • 我同意@FelixKling。如果var something = something || {}new 作用域的第一行,那么无论外部作用域中是否存在名为something 的变量,结果将始终为var something = {}
      【解决方案5】:

      和做的一样:

      var something = ( something ) ? something : {};
      

      其中( something ) 是对真值或假值的评估。如果为真(something 存在),它将等于自身,否则为空对象。

      【讨论】:

        【解决方案6】:

        这个结构对于覆盖现有数据非常有用。假设我们正在处理多个 Javascript 文件,并且我们希望在某个对象上共享一些数据。

        a.js

        var share = window.share = share || { };
        share.thisIsA = true;
        

        b.js

        var share = window.share = share || { };
        share.thisIsB = true;
        

        如果我们有两个以上的文件并且我们异步加载这些文件(我们不能保证顺序),我们不会覆盖之前定义和填充的全局 share 对象。这是命名空间对象配置对象的一种非常常见的做法。

        另一个非常常见的用例是创建默认值。比如

        function foo( option ) {
            option = option || 'something';
        
            if( option === 'foobar' ) {} // ...
        }
        

        在那里,如果函数在没有参数的情况下被调用,我们使用模式来为我们的选项参数提供至少一个已知和定义的值。例如,您可以在插件代码中经常看到这一点。

        【讨论】:

          【解决方案7】:

          看起来更像是在确保某物是可以挂在上面的物体。设置默认值。

          一旦你调用 var something 或将其设置为函数的参数,该范围内的所有实例都是新变量,你无法访问更高范围内的实例。

          (function() {
            var something = 'foo';
          
            (function() {
              var something = something || 'bar';
          
              console.log(something);
            })();
          
            console.log(something);
          })();
          

          会输出

          'bar'
          'foo'
          

          【讨论】:

            【解决方案8】:

            javascript中的OR构造函数接近这个函数

            function or(a, b)
            {
              if(a) return a;
              else return b;
            }
            

            当“a”计算为真时,它甚至不检查“b”(也不执行它,但它不是函数案例)。此外,它返回纯“a”而不将其更改为布尔值。非布尔变量“ORed”的构造计算为第一个变为布尔真。它广泛用于无法支持某些东西的地方。

            var functionDoingSomethingCrossBrowser = functionOnMsie 
                                                  || functionEverywhereElse;
            

            这与{}(新对象)运算符相结合,当您的“某物”在范围内不可用时(很可能未定义,其计算结果为假),用空对象填充变量。

            【讨论】:

              猜你喜欢
              • 2018-03-22
              • 1970-01-01
              • 2014-07-13
              • 2018-10-29
              • 2016-12-28
              • 1970-01-01
              • 2019-03-05
              • 1970-01-01
              • 2022-01-13
              相关资源
              最近更新 更多