2010-09-20 158 views
9

有時我會看到這樣的代碼:JavaScript對象實例化

var Obj = Obj || {}; 

這是什麼呢?我已經成功編寫

array = array || []; 

實例化一個數組,如果它尚未被實例化,但是我想知道更多的關於這個機制。

+1

類似於c#''''運算符,但是javascript沒有定義一個新的運算符。 http://msdn.microsoft.com/en-us/library/ms173224.aspx – lincolnk 2010-09-20 21:40:55

回答

11

該技術試圖利用一種叫做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是未定義的,除非它是在相同的範圍內聲明(包括被聲明爲函數的參數,如果有的話)...所以{}將被評估。 (在T.J.Crowder的評論中提供的Link to an explanation of var)。

以下代碼創建僅當Obj一直先前聲明一個空對象,現在falsy:

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未申報的情況下。


注:我提到這一點在倒數第二個例子的意見,但要了解2個原因,一個變量可以在JavaScript中未定義是很重要的。

  1. 變量可以是未定義的,因爲它從未被聲明。
  2. 一個變量可以是未定義的,因爲它已被聲明但沒有賦值給它。

變量可以使用var關鍵字聲明。爲未聲明的變量賦值會創建變量。

試圖使用未定義的變量也會導致運行時錯誤。使用已聲明的未定義變量是完全合法的。這種差異使得使用Obj = Obj || {};非常棘手,因爲如果Obj未被聲明或者它是先前存在的變量,則前面的語句沒有有意義的形式。

+3

*「如果Obj已經存在,則在正常情況下,上述評估將停止在var Obj = Obj * *錯誤。有一個'var Obj'這個事實意味着在Obj ||之前該行的一部分會進行評估(在處理完'var Obj'部分後會發生這種情況),Obj **將會被定義爲不確定的,所以如果包含一個「Obj」範圍。只有當聲明是真實的時候,如果在同一範圍*(函數)內有另一個* var * Obj',這是非常不尋常的。 – 2010-09-20 21:56:09

+0

@ T.J。 Crowder - 正是在那些不尋常的時代,這很有用。最常見的用法是設置一個默認值,如果'Obj'參數沒有被傳入函數 - 看看這兩個jsFiddles:http://jsfiddle.net/Ee7w3/ ---- http: //jsfiddle.net/34rbS/ – 2010-09-20 22:07:11

+0

@彼得:那些小提琴中的'var'毫無目的,並且模糊了真正發生的事情。你仍然在修改這個論點。 http://jsbin.com/emulo/2(沒有試圖把這個變成一個jsbin與小提琴!;-)) – 2010-09-20 22:11:14

2
var Obj = Obj || {}; 

我認爲var這裏沒有必要。它應該是:

Obj = Obj || {}; 

其中Obj在別處定義。如果空白對象爲空或者保持不存在,這將簡單地將Obj分配給空對象。您也可以保留var關鍵字,在這種情況下,即使它不在此語句之前,它也會確保該對象已被聲明。

相同的數組:如果它爲空它將分配給一個空數組。

3

的機制是有點不尋常:與大多數語言,JavaScript的||符不返回truefalse。而是返回第一個「真值」值的右邊值。例如:

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

由於Darin said,你var Obj = Obj || {};可能不是一個字面上的報價,更可能是這樣的:

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

...這意味着,「如果主叫方沒有給我的東西truthy爲param,使用一個東西。」

0

理解此語法的關鍵是,JavaScript中布爾值或(或)和/或表達式的結果是最後評估的組件。正如其他評論者所指出的那樣,JavaScript的短路與此功能一起使用,以有條件地設置值arrayObj

Obj = Obj || {}; 

這意味着Obj設置爲表達式Obj || {}的值。如果Obj是「真」,這意味着它的計算結果爲真(對於一個對象,這意味着它存在),表達式的結果是Obj,因爲表達式短路。但是,如果Obj是「假」(不存在),則必須評估表達式的第二部分。因此,在這種情況下,表達式的值是{}