2011-01-11 31 views
28

我讀過,建議不要在您的HTML中多次實例化jQuery。這對我來說非常有意義,但是: 反正不是Javascript單線程?將jQuery留在後面,瀏覽器如何執行這些多個腳本標記?平行或一個接一個?HTML中多個<script>標記的含義

謝謝你,菲利普

+4

「我讀過,不建議在你的HTML中多次實例化jQuery」:你有鏈接嗎? – Nabab 2011-01-11 15:42:36

+0

不抱歉,也許我也有錯誤或錯過了一個細節。實際上jQuery是無狀態的,但插件可以(並且必須在某些情況下)多次實例化。 – Philip 2011-01-11 16:38:42

回答

32

答案很簡單:

在一個簡單的場景(標籤是原始的HTML文本的一部分),瀏覽器絕對執行它們一個接一個。

不同告誡

的JavaScript的詳細討論並不一定是單線程(這取決於你的JavaScript引擎的實現,例如見Web Workers)。

但是,個人<script>標籤是順序執行。

僅供參考,請參閱JavaScript: The Definitive Guide。引用章節「12.3。執行JavaScript程序」:

出現在和標記之間的JavaScript語句按照外觀順序執行;當一個文件中出現多個腳本時,腳本將按照它們出現的順序執行。如果腳本調用document.write(),那麼傳遞給該方法的任何文本都將在結束標記後立即插入文檔中,並在腳本完成運行時由HTML分析器進行分析。同樣的規則適用於包含具有src屬性的單獨文件的腳本。


請注意,上面是唯一真正在標籤代碼「直線上升」的執行。 - 看到這個答案的最後一節

  • setTimeout()電話(杜)

  • defer attribute

  • <script>標籤的動態attachement:訂單可以,但是,受到影響。


作爲警告,請注意,JavaScript代碼通過<script src="xxxx" />外部加載仍然會按順序執行,但是,這是很有可能的是,瀏覽器將下載並行代碼 - 依賴在瀏覽器上執行(但仍然按照正確的順序安排執行下載的代碼片段)。

這個告誡是很重要的,如果你想有一些奇怪的黑客,而JavaScript源的URL實際上是一個CGI腳本,它執行某些操作,並且嘗試依賴於腳本中邏輯的正確下載順序。

同樣,它不會影響您的瀏覽器JS引擎對這些腳本片斷的執行順序。


然而,一個更重要的告誡是,如果你真的附上<script>標籤與動態外部資源(例如,通過appendChild()調用),根據this SO post,還有MSDN blog the post was based on,非IE瀏覽器不保證執行順序!這取決於哪個標籤的代碼先完成下載!

+1

謝謝你這個百科全書的答案! – Philip 2011-01-11 16:37:59

0

瀏覽器在處理過程中不會將所有JavaScript都編譯成一個「文件」。例如,如果您在多個文件中有多個$(document).ready()調用,當瀏覽器預處理頁面時,它基本上將所有內容壓縮以供執行 - 並按照「看到」的順序依次運行它。

1

瀏覽器按順序執行JavaScript(對於jQuery也是如此,因爲jQuery只是JavaScript)。

至於在HTML中有多個腳本標記,沒有理由說這是一個問題。正如Nabab所問,我會對看到你的消息來源感興趣。

3

實例化jQuery對象的調用次數越少,所擁有的開銷就越小 - 但即使您正在爲在第二代硬件上運行的舊瀏覽器設計,也要小心微調優化。剖析您的應用程序並修復實際上是瓶頸的部分。

至於瀏覽器處理多個腳本標記的方式 - 不同的瀏覽器,瀏覽器,版本之間,有時甚至從操作系統到操作系統。所有瀏覽器按文檔順序執行每個腳本標籤:

<script src="scripts/some_script.js"></script> <!-- Executed 1st --> 
<script src="scripts/some_other_script.js"></script> <!-- Executed 2nd --> 
<script> 
// Some JavaScript 
</script> <!-- Executed 3rd --> 
<script> 
// Some More JavaScript 
</script> <!-- Executed 4th --> 

但是,其他行爲未定義,並且存在變化。例如,Opera(至少在版本10.6的Windows XP上)在其自己的上下文中運行了每個腳本標記 - 因此,如果在第四個腳本塊中引用,則第三個腳本塊中的局部變量將超出範圍。

<script> 
var i = 42; 
</script> 
<script> 
alert(i); 
// Alerts "undefined" in Opera, but 42 in Firefox. 
</script>