2013-03-30 426 views
6

我見過很多次fn && fn()if (fn) fn()的優化。「if(fn)fn()」或「fn && fn()」

我的問題是:爲什麼?以及兩種解決方案的生成代碼是什麼?

+2

你是什麼意思的「生成的代碼」? – Kobi

+0

@Kobi我猜他意味着什麼問題的JavaScript被編譯爲 - 低級代碼。 – kba

+0

@ kobi,kba是對的,我的意思是低級代碼,彙編程序。 –

回答

13

&&運營商在JavaScript是短路,這意味着如果左側是false,則根本不評估右側。這就是爲什麼fn && fn()是安全的,即使fn有錯(nullundefined等)。

「代碼生成」將完全依賴於JavaScript引擎,但我希望它是在兩種情況下(在&&if)頗爲相似。

這不是在運行速度更快意義上的「優化」,而是被更短的寫(尤其如此,如果像我一樣,你永遠離開關閉{}陳述if)感。它的缺點是略微對那些對語言不熟悉的人不太清楚,但它是一個很快學會的成語。

+0

執行'typeof fn ===「function」'會不會更安全? – Antony

+0

@Antony:是的,會的。在代碼期望函數或沒有任何內容的地方(例如,一個可選的函數參數),你會看到這種習慣用法,如果你給它一些東西但失敗了,人們往往會很滿意,但是你給它的東西並不是'一個函數,理論上這個函數的文檔(例如)說你可以提供一個函數或什麼都不提供,但不是函數或(比如說)字符串。 :-)另外,某些引擎上的某些主機提供的函數具有'typeof'''''''''''(可悲),但仍然可以調用。 –

2

因此,通過if (fn) fn(),您需要確保fn在執行之前已存在。 if條件檢查布爾值或表達式,在JavaScript中,任何falsy值都可以在if布爾檢查條件中變爲false值。 Falsy值可能是:

  • 不確定
  • 空字符串 ''
  • 數0
  • 數爲NaN(是的, '不是一個數字' 是號,它是一種特殊 數)

任何其他值將是一個truthy VALU即

因此,如果fnnullundefined值,那麼if檢查將防止您執行非函數對象。

通過fn && fn(),你正在做的是相同的:在JavaScript中,布爾表達式爲懶惰檢查,這意味着如果所述第一部分,在一個&&操作,是falsy那麼第二部分將不被執行。因此,使用此功能,您可以保護您的代碼免於執行非函數對象。

fn && fn()不是性能方面的優化版本,而是寫入的簡短版本。

這兩個代碼片段都需要一個前提條件:函數fn可以是未定義的函數或實際的函數對象。如果在你的代碼中,fn有被其他類型,如字符串的目標的可能性,你需要在執行前添加類型檢查,如:

if (fn instanceof Function) fn()

0

在優化方面,恕我直言,我會說它是因爲它是一種更好的方式,使它成爲一條線,如果沒有犧牲大括號和犧牲可讀性,但它不會使代碼更快執行