2015-04-16 41 views
16

我發現它here這是什麼javascript表示法?

;(function ($, window, document, undefined) { 
//code 
}(jQuery, this, this.document)); 

這是我第一次看到這樣的事情。它是什麼以及它是如何解釋的?我不明白爲什麼它必須通過this和this.document,以及'undefined'的含義。

的原因,我問的是,因爲我把它在我的網頁和

if($('ul.mtree').length) 

返回false,儘管當我在控制檯中鍵入它返回true。

+1

@ ZachLeighton,這個問題有點令人困惑,但我認爲喬治詢問關於jquery文件加載的問題 –

+0

我不明白爲什麼它必須通過this和this.document,以及'undefined' –

+0

@NathanKoop很好抓,我很快看了一眼,看到了分號就是這樣。 –

回答

16

第一個分號;除了可能忘記分號的其他代碼外,還設置了以下代碼。這是非常重要的,因爲如果沒有找到分號,那麼這些元素會嘗試運行前面的語句作爲函數。

對於其餘的代碼,我們只是聲明一個「內聯」函數,將立即執行,其中參數$, window, document然後從全局範圍實例化爲jQuery, this, this.document(分別)。這主要是爲了讓您可以在新的jQuery插件中使用「$」而不用擔心$是否被其他地方覆蓋。您可以確定$jQuery相同。

瞭解更多關於從OP「保護$別名和添加範圍」 here

更新:

對於if語句返回false,請確保您的HTML是在調用的時候加載您的if聲明。一個快速的方法來做到這一點,是它包裝在一個$(document).ready方法,像這樣:

$(document).ready(function() { 
    if($('ul.mtree').length) { 
     alert("got 'em!"); 
    } 
}); 
+1

只需要提一下:它對於js代碼的縮小很有幫助。 –

+0

是的!好點@RoyiNamir –

+1

另外:你忘了提到undefined可能被用戶代碼覆蓋(我不認爲現在是這種情況),但是最好不向變量發送任何東西,所以你可以肯定它有'undefined '價值 –

3

這是一個立即執行的功能。 The;在開始時,可​​以防止縮小後的潛在語法錯誤。

函數本身提供參數的範圍,而不是在全局範圍內引用它們。它還提供了使用該函數定義的局部變量的隱私。通過undefined傳遞的最終參數有點令人困惑,它可以防止在全局範圍內對未定義表示的惡意更改。

如果你是谷歌的JavaScript條款,如自執行功能,全局範圍,閉包,模塊模式可用的資源很多。

+0

關於「undefined」的好電話。我錯過了。 –

1

或許,該代碼是應該固定在其中$windowdocument已陰影與其他值的情況下:

(function() { 
var window = 123, 
    document = 'abc', 
    $ = Function.prototype; 
})(); 

然後,

  • $jQuery使用的速記和其他圖書館。該代碼假定jQuery未被其他事物遮蔽,因此它會創建一個名爲$的變量,其值爲jQuery
  • this是一個關鍵字。如果未以非嚴格模式顯式設置,則它將成爲全局對象。所以你的代碼創建了一個帶有該值的局部變量window。請注意,這是危險的,因爲this可能已設置爲某個值,或者在嚴格模式下爲undefined
  • 假設this是全局對象,this.document將是文檔對象。
  • undefined是全局對象的一個​​屬性,它沒有ECMAScript 3中的ReadOnly屬性,所以它可以被覆蓋。你的代碼創建一個局部變量而不分配任何值,所以它變成了真正的未定義的。這是ECMAScript 5以來不再需要的,因爲window.undefined的[[Configurable]]和[[Writable]]屬性設置爲false

然後,

(function() { 
var window = 123, 
    document = 'abc', 
    $ = Function.prototype; 
    (function($, window, document, undefined) { 
     // `$`, `window`, `document` and `undefined` have been restored 
    })(jQuery, this, this.document); 
})(); 
2

這可能會有幫助,包括你有不正常的代碼的副本。

但是,爲了回答關於爲什麼if($('ul.mtree').length)可以在控制檯返回true的問題,但false頁面可能取決於時機(例如函數執行的DOM加載之前)。當你加載控制檯檢查值時,DOM被加載並返回true。

請務必在頁面末尾包含您的JS,或者僅在文檔加載後調用。

+0

包含OP –

+0

好調用的「文檔加載」語法可能會有所幫助,因爲我不想對OP的代碼做任何假設,所以我最初將其忽略掉了。我會編輯它,但看起來像您已經編輯你的答案,包括一個樣本,所以我會離開我一個人來限制重複。 – MichaelM

1

如果我理解正確的話你的問題,符號;提前函數語句的功能,如

(function(){ 
    console.log('no name'); 
})(); 

(function(){ 
    console.log('no name') 
}()); 

-function(){ 
    console.log('no name'); 
}(); 

+function(){ 
    console.log('no name'); 
}(); 

~function(){ 
    console.log('no name'); 
}(); 

!function(){ 
    console.log('no name'); 
}(); 

你會看到的符號,如「()」,「 - 」,」 +」, '〜', '!'

並且符號的功能是將函數語句解析成表達式並立即執行該函數!

但我建議你只用'()'來執行函數語句,因爲它是例程中使用的正式方法和常規方法。