代码之家  ›  专栏  ›  技术社区  ›  Josh K

javascript对象实例化

  •  9
  • Josh K  · 技术社区  · 14 年前

    有时我会看到这样的代码:

    var Obj = Obj || {};
    

    这是做什么的?我写得很成功

    array = array || [];
    

    如果一个数组还没有被实例化的话,就实例化它,不过我想知道更多关于这个机制的信息。

    4 回复  |  直到 14 年前
        1
  •  11
  •   Peter Ajtai    14 年前

    这项技术试图利用 short circuit evaluation …但在JavaScript中,这是很棘手的,如果您试图利用它进行对象实例化,结果会非常危险。

    短路评估背后的理论是,OR语句只能在第一个语句之前进行评估 true 值。因此,如果OR语句的前半部分为真,则不对其后半部分进行计算。这适用于javascript……

    但是,JavaScript的特性,特别是如何处理未声明的变量,使得它成为一种必须非常小心地用来实例化对象的技术。

    以下代码创建一个空对象,除非obj以前在同一范围中声明:

    var Obj = Obj || {}; // Obj will now be {}, unless Obj was previously defined
                         //  in this scope function.... that's not very useful...
    

    这是因为之后 var Obj , Obj 除非在同一范围内声明,否则将未定义( 包括 声明为函数的参数(如果有)。所以 {} 将被评估。( Link to an explanation of var 在T.J.Crowder的评论中提供)。

    以下代码仅在以下情况下创建空对象 OBJ 已经 以前声明的 现在是不稳定的:

    Obj = Obj || {};     // Better make sure Obj has been previously declared.
    

    如果在以下情况下使用上述行: OBJ 以前没有声明过,会有运行时错误,脚本将停止!

    例如,此javascript根本不会进行评估:

    (function() {
        Obj = Obj || "no Obj"; // error since Obj is undeclared JS cannot read from 
        alert(Obj);​            //   an undeclared variable. (declared variables CAN
    })();                      //   be undefined.... for example "var Obj;" creates 
                               //   a declared but undefined variable. JS CAN try
                               //   and read a declared but undefined variable)
    

    jsFiddle example

    但这个javascript总是 OBJ 到“没有对象”!

    var Obj ="I'm here!";
    (function() {
        var Obj = Obj || "no Obj"; // Obj becomes undefined after "var Obj"...
        alert(Obj);  // Output: "no Obj"
    })();​
    

    jsFiddle example

    所以在javascript中使用这种短路评估是危险的,因为您通常只能在表单中使用它

    Obj = Obj || {};
    

    会失败的 正是你最想让它工作的时候 …如果obj未声明。


    注: 我在倒数第二个例子的注释中提到了这一点,但是理解变量在JavaScript中无法定义的两个原因是很重要的。

    1. 变量不能未定义,因为它从未声明。
    2. 变量不能未定义,因为它已声明,但尚未赋值。

    变量可以使用 var 关键字。将值赋给未声明的变量将创建该变量。

    尝试使用未声明的未定义变量会导致 运行时错误 . 使用已声明的未定义变量是完全合法的。这就是为什么使用 Obj = Obj || {}; 很棘手,因为如果 OBJ 不是未声明的,就是以前存在的变量。

        2
  •  3
  •   Community rohancragg    7 年前

    这种机制有点不寻常:与大多数语言不同,JavaScript的 || 操作员有 返回 true false . 相反,它返回第一个“truthy”值 右边的值。例如:

    alert("a" || "b");              // alerts "a", because non-blank strings are "truthy"
    alert(undefined || "b")         // alerts "b", because undefined is falsey
    alert(undefined || false || 0); // alerts "0", because while all are falsy, 0 is rightmost
    

    更多内容 this blog post .

    AS Darin said 你的 var Obj = Obj || {}; 可能不是字面引用,更可能是这样的:

    function foo(param) {
        param = param || {};
    }
    

    …意思是,“如果来电者没有给我一些真实的东西 param ,使用对象。“

        3
  •  2
  •   Darin Dimitrov    14 年前
    var Obj = Obj || {};
    

    我认为 var 这里没有必要。应该是:

    Obj = Obj || {};
    

    在哪里? Obj 在其他地方定义。这将简单地分配 OBJ 如果空对象为空或保留为非空对象。你也可以离开 var 关键字,在这种情况下,它将确保对象被声明,即使它不是在此语句之前。

    对于数组也是这样:如果它为空,则将其分配给空数组。

        4
  •  0
  •   jhurshman    14 年前

    理解这种语法的关键是,javascript中布尔或(或和)表达式的结果是最后一个计算的组件。正如其他评论者所指出的,JavaScript的短路正与此功能一起使用,以有条件地设置 array Obj .

    Obj = Obj || {};
    

    这意味着obj被设置为表达式的值 Obj || {} . 如果obj为“真”,表示它的计算结果为“真”(对于对象,表示它存在),则表达式的结果为 OBJ 因为表达式短路。但是,如果 OBJ 为“false”(不存在),必须计算表达式的第二部分。因此,在这种情况下,表达式的值是 {} .