有時我會看到這樣的代碼:JavaScript對象實例化
var Obj = Obj || {};
這是什麼呢?我已經成功編寫
array = array || [];
實例化一個數組,如果它尚未被實例化,但是我想知道更多的關於這個機制。
有時我會看到這樣的代碼:JavaScript對象實例化
var Obj = Obj || {};
這是什麼呢?我已經成功編寫
array = array || [];
實例化一個數組,如果它尚未被實例化,但是我想知道更多的關於這個機制。
該技術試圖利用一種叫做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)
但此Javascript將始終設置Obj
爲 「無目標文件」!
var Obj ="I'm here!";
(function() {
var Obj = Obj || "no Obj"; // Obj becomes undefined after "var Obj"...
alert(Obj); // Output: "no Obj"
})();
因此,使用這種類型的Javascript短路的評價是很危險的,因爲你通常只能用它的形式
Obj = Obj || {};
將失敗正是時候你最想讓它工作 ...在Obj未申報的情況下。
注:我提到這一點在倒數第二個例子的意見,但要了解2個原因,一個變量可以在JavaScript中未定義是很重要的。
變量可以使用var
關鍵字聲明。爲未聲明的變量賦值會創建變量。
試圖使用未定義的變量也會導致運行時錯誤。使用已聲明的未定義變量是完全合法的。這種差異使得使用Obj = Obj || {};
非常棘手,因爲如果Obj
未被聲明或者它是先前存在的變量,則前面的語句沒有有意義的形式。
*「如果Obj已經存在,則在正常情況下,上述評估將停止在var Obj = Obj * *錯誤。有一個'var Obj'這個事實意味着在Obj ||之前該行的一部分會進行評估(在處理完'var Obj'部分後會發生這種情況),Obj **將會被定義爲不確定的,所以如果包含一個「Obj」範圍。只有當聲明是真實的時候,如果在同一範圍*(函數)內有另一個* var * Obj',這是非常不尋常的。 – 2010-09-20 21:56:09
@ T.J。 Crowder - 正是在那些不尋常的時代,這很有用。最常見的用法是設置一個默認值,如果'Obj'參數沒有被傳入函數 - 看看這兩個jsFiddles:http://jsfiddle.net/Ee7w3/ ---- http: //jsfiddle.net/34rbS/ – 2010-09-20 22:07:11
@彼得:那些小提琴中的'var'毫無目的,並且模糊了真正發生的事情。你仍然在修改這個論點。 http://jsbin.com/emulo/2(沒有試圖把這個變成一個jsbin與小提琴!;-)) – 2010-09-20 22:11:14
var Obj = Obj || {};
我認爲var
這裏沒有必要。它應該是:
Obj = Obj || {};
其中Obj
在別處定義。如果空白對象爲空或者保持不存在,這將簡單地將Obj
分配給空對象。您也可以保留var
關鍵字,在這種情況下,即使它不在此語句之前,它也會確保該對象已被聲明。
相同的數組:如果它爲空它將分配給一個空數組。
的機制是有點不尋常:與大多數語言,JavaScript的||
符不不返回true
或false
。而是返回第一個「真值」值或的右邊值。例如:
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
,使用一個東西。」
理解此語法的關鍵是,JavaScript中布爾值或(或)和/或表達式的結果是最後評估的組件。正如其他評論者所指出的那樣,JavaScript的短路與此功能一起使用,以有條件地設置值array
或Obj
。
Obj = Obj || {};
這意味着Obj設置爲表達式Obj || {}
的值。如果Obj是「真」,這意味着它的計算結果爲真(對於一個對象,這意味着它存在),表達式的結果是Obj
,因爲表達式短路。但是,如果Obj
是「假」(不存在),則必須評估表達式的第二部分。因此,在這種情況下,表達式的值是{}
。
類似於c#''''運算符,但是javascript沒有定義一個新的運算符。 http://msdn.microsoft.com/en-us/library/ms173224.aspx – lincolnk 2010-09-20 21:40:55