簡體   English   中英

JavaScript模塊模式(function(){})(); vs區塊聲明

[英]JavaScript Module Pattern(function(){})(); vs block statement

我之前看到了一個使用我的"Weird"示例的問題的答案,我想知道這兩種方法是否有任何好處。

一些HTML:

<span id="them">Hey</span>
<span id="me">Hey</span>

之間有什么區別?

(function()//doing this
{
    them.innerHTML = "Weird<br>";
})();

me.innerHTML = "Not so weird<br>";//and doing this

甚至,當人們可以將腳本放在正文底部時,為什么還要使用window.onload 還是僅僅是個人喜好問題?

  1. 您的兩個示例之間沒有區別。 您的第一個示例創建了一個立即執行的匿名函數(稱為立即調用函數表達式)。 您的第二個示例僅執行相同的代碼。

  2. 您必須等到瀏覽器讀取所有HTML元素,然后才能使用JavaScript對其進行更改。 當頁面完全加載時, onload事件觸發,那時瀏覽器知道所有HTML元素。 但是,瀏覽器直到頁面完全加載后才會觸發onload事件,這意味着瀏覽器將等到大圖像完全加載之后-即使瀏覽器已經解析了HTML的其余部分-您的JavaScript無需等待,直到圖像加載完成。 由於瀏覽器在圖像加載完成之前就知道了所有HTML,因此沒有理由阻止JavaScript較早執行。

一旦人們發現onload在等待執行JavaScript之前等待了很長時間,人們就開始將其JavaScript放在結束的<body>標記之前(不使用onload ),以便在所有HTML解析之后,JavaScript便會立即執行。 (除<body>結束標記外),這樣它們的JavaScript可以比使用window.onload更快地開始執行。

現在,像jQuery這樣的JavaScript庫都有一個事件,當瀏覽器了解所有HTML時,即使頁面未完全加載(例如,由於圖像未完全加載),該事件也會觸發。

  • 您的第一個代碼段:是模塊模式立即調用的函數表達式(IIFE)

     (function()//doing this { them.innerHTML = "Weird<br>"; })(); 
  • 當Javascript編譯器遇到此問題時,遇到();時將立即調用該函數(); 並將變量和函數保持在其范圍內。

    您必須閱讀Java腳本設計模式才能更好地了解其用法和優點。

  • 第二個代碼段:只是一個JavaScript語句。

     me.innerHTML = "Not so weird<br>";//and doing this 

    當JavaScript編譯器遇到此問題時,將立即執行它。

請記住,兩個代碼片段的執行都取決於其放置位置。

  • 因此,回答您的其他問題。 window.onload是HTML DOM完全加載且瀏覽器可以讀取其所有元素時觸發的事件。

在您的簡單示例中,兩種情況的結果沒有區別。 兩者完成同一件事。

使用此結構的原因:

(function()//doing this
{
    them.innerHTML = "Weird<br>";
})();

是創建一個函數范圍,該函數范圍可用於保存私有或臨時變量,或者創建一個閉包而不將變量內部暴露給外界。

至於第二個問題, window.onload觸發時間與放置在正文末尾的腳本的觸發時間不同,這是因為window.onload在頁面所需的所有同步資源(例如腳本和圖像)完成加載后觸發。 可以使用它來完成所有這些資源的加載時得到通知,或者可以將其用作無法安全地放置在頁面末尾的代碼,以便在頁面准備就緒時安全地使用它,盡管通常不必這樣做。請等待那么長時間,以確保DOM安全。

在上述情況下,使用第一種方法沒有優勢。

但是,在需要創建一些變量/方法但又不想污染全局名稱空間的情況下,第一種方法更可取

經過深思熟慮,編寫額外的(function(){})();有好處(function(){})(); 如圖所示(假設代碼很大):

(function()
{
    var text = "Span 'them' text!";
    them.innerHTML = text;
    //Many lines of code
})();

(function()
{
    me.innerHTML = text;//will throw 'text is undefined'
    //Many lines of code
})();

這對於調試多行代碼非常方便,調試器將識別出錯誤並“指向”錯誤。

而在此示例中:

var text = "Span 'them' text!";
them.innerHTML = text;
//Many lines of code
//...
me.innerHTML = text;

您的“錯誤”(調試器非常滿意)將很難追蹤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM