JavaScript对象实例化

Jos*_*h K 9 javascript

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

var Obj = Obj || {};
Run Code Online (Sandbox Code Playgroud)

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

array = array || [];
Run Code Online (Sandbox Code Playgroud)

要实例化一个尚未实例化的数组,不过我想了解更多关于它的机制.

Pet*_*tai 11

该技术试图利用一种称为短路评估的东西......但它在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...
Run Code Online (Sandbox Code Playgroud)

这是因为后var Obj,Obj将不确定,除非它是在相同的范围内声明(包括被声明作为参数的功能,如果有的话)....所以{}进行评价.(链接到 TJ Crowder评论中提供的var的解释).

以下代码仅Obj先前声明并且现在为假的情况下才创建空对象:

Obj = Obj || {};     // Better make sure Obj has been previously declared.
Run Code Online (Sandbox Code Playgroud)

如果在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)
Run Code Online (Sandbox Code Playgroud)

jsFiddle例子

但是这个Javascript总是会设置Obj为"no Obj"!

var Obj ="I'm here!";
(function() {
    var Obj = Obj || "no Obj"; // Obj becomes undefined after "var Obj"...
    alert(Obj);  // Output: "no Obj"
})();?
Run Code Online (Sandbox Code Playgroud)

jsFiddle例子

因此,在Javascript中使用这种类型的短路评估是危险的,因为您通常只能在表单中使用它

Obj = Obj || {};
Run Code Online (Sandbox Code Playgroud)

当你最希望它工作的时候,哪个会失败?在Obj未申报的情况下.


注意:我在倒数第二个例子的注释中提到了这一点,但重要的是要理解在Javascript中未定义变量的两个原因.

  1. 变量可以是未定义的,因为它从未声明过.
  2. 变量可以是未定义的,因为它已声明但未分配给它的值.

可以使用var关键字声明变量.为未声明的变量赋值会创建变量.

尝试使用未声明的未定义变量会导致运行时错误.使用已声明的未定义变量是完全合法的.这种差异使得使用Obj = Obj || {};如此棘手,因为如果Obj未声明或者它是先前存在的变量,则前一语句没有有意义的形式.

  • *"如果Obj已存在,则上述评估将在var Obj = Obj停止"*正常情况下错误.事实上,有一个`var Obj`意味着到`Obj ||时 {}`该行的一部分进行求值(在处理`var Obj`部分之后很好地发生),`Obj`**将是**未定义的,所以如果在一个含有的'Obj`则无关紧要范围.该语句唯一的时间是真的,如果在同一范围内*(函数)中有另一个*`var Obj`*,这是非常不寻常的. (3认同)