2012-11-19 43 views
6

我經常使用var options = options || {}作爲默認爲空對象的方式。它通常用於初始化選項對象,以防未在函數調用的參數中傳遞該對象。var options = options ||之間的區別{}`和`選項|| (options = {})`

事情是我已經在幾個地方看過(博客文章,源代碼),options || (options = {})更好地表達了開發者的意圖。有人可以詳細說明嗎?我沒有看到兩者之間的功能差異,所以我必須在這裏丟失一些東西。

---編輯

我在幾個地方Backbone.js的源代碼所看到的,像https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L273

我想我也看到了在jQuery的源代碼了。並且在多個Js寫作風格指南中蓬勃發展。

---編輯2代碼例如:

var func = function(param, options) { 
    // How I do it 
    var options = options || {}; 
    // How I should do it in the "same" way 
    options = options || {}; 
    // The "other" way 
    options || (options = {}); 

} 
+0

你能鏈接到這些職位的一些? –

+0

這是主觀的恕我直言,我個人喜歡你喜歡的那個,他們真的做同樣的事情。 – 2012-11-19 12:14:15

+1

我通常會做'選項=選項|| {}',而不用'var'重新聲明變量。可惜在Javascript中沒有'|| =' – Kos

回答

3

他們應該做同樣的事情,但有一個更好的辦法。

從理論上講,第二個,只有在值是假的時才分配,可以消除分配並且更快。事實上,在jsperf中,我們看到它是(12%)。

事實上,如果顯式聲明是一樣快的條件,然後指派:

if(!options) 
    options = {}; 

Try the test on your browser/machine

我認爲明確的if是最清楚的,沒有懲罰。

編輯:

如果你期待中的功能傳遞一個對象,那麼我認爲更好的測試是:

if(typeof options !== 'object') 
    options = {}; 

這將確保你有一個對象後,即使它是空的。任何其他測試(對於未定義的或虛假的)都將允許真正的非對象通過,如非零數字或非空字符串。然而,正如jsperf所顯示的那樣,這會慢15%左右。既然你只是在進入一個處理對象的函數時這麼做,那麼我認爲這是一個值得平衡的選擇,並且是幾乎比總是分配的慢。

+0

我試過了jsperf,使用Chrome 23。基本沒有區別。 – DjebbZ

+0

@DjebbZ:的確,做最可讀的,除了最後一次測試的明確性之外沒有其他好處。 –

4

沒有一個功能上的差異。

第二個構造只是(主觀)看起來就像它做的比第一個構造更多。

相反的觀點是,第一個構造是一種常見模式,所以更容易確認做它做的事情。

+0

同意,對於不太接近JavaScript的人來說,第一個符號看起來更容易理解。 – naivists

5

有沒有真正的區別,假設你的意思是:

function fn(options) { 
    // type a 
    options = options || {}; 

    // type b 
    options || (options = {}); 
} 

晴偏好的問題,我認爲,(a)是一個整體更加清晰,我不喜歡在LHS沒有賦值語句。

1

這兩者之間確實沒有功能差異,即使它們的機制不相同。

第一種形式將局部變量options設置爲等於參數options,或者如果參數具有僞造值(例如,如果它未提供),則將其設置爲空對象。

第二種形式的計算結果爲參數options的值(如果不是虛假的),否則計算結果爲空對象賦值給該參數。所以與第一種形式的區別在於,如果options是真的,則不執行任務。

個人我考慮第二種形式爲的

if(!options) { 
    options = {}; 
} 

較少可讀的版本,其在兩個功能力學相同。

1

沒有功能上的差異,這個想法是,options || (options = {});接近什麼程序員真的想表達的,這實際上是:

if (typeof options == "undefined") { 
    options = {}; 
} 

||運營商是用來製造更短的代碼,而不是更清晰的代碼。

+0

falsy和undefined之間有相當大的差距,所以如果你真的想覆蓋undefined,那就明確地做。 –

+0

@PhilH:是的,存在差距,但無論如何都沒有配備版本的代碼來處理間隙中的所有值。這兩個版本都允許一些在這個上下文中無用的值,比如'true',可以讓其餘的代碼窒息。 – Guffa

+0

非常真實。這是動態類型語言的一個缺點。 –

0

絕對是主觀的,但我不會使用第二個。

原因:我覺得表達式的任何位置比頂級=混淆更深。

一些像這樣的C程序員(我曾經這樣做過),他們通過做額外的東西來使得任務更清晰......讓整個表達式看起來不熟悉。爲什麼要打擾,如果你可以直截了當?

最明確的將可能是:

if (!options) options = {}; 
2

有一個功能差異:一個使用var,另一個不使用。如果在當前範圍內存在options變量不存在的可能性,則使用var要好得多,而不是隱含地泄漏到外部作用域中的風險options

如果選項是保證存在(例如,它的參數包括options的函數內),所述兩個語句是功能上相同,因此問題簡化爲的options = options || {}options || (options = {})相對文體優點。就個人而言,我幾乎看不出什麼區別:它們都需要與JavaScript的||操作符相同的知識,因此,一旦從等式中刪除了該因素,我可能會傾向於使用options = options || {},因爲它更簡單,更容易閱讀。在這兩種情況下,開發者的意圖似乎都很清楚。

+0

當然可以。我忘了添加一些代碼來使其明確,其中'options'變量實際上存在於函數參數中。所以雖然你的觀點非常有效,但對我的情況沒有影響。 – DjebbZ