簡體   English   中英

JavaScript段代碼解釋

[英]JavaScript piece of code explanation

查看這段 JavaScript 代碼:

(function (w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    w.addEventListener ? w.addEventListener("load", loader, false) :
                         w.attachEvent("onload", loader);
}) (window, document);

為什么這段代碼的作者要用這種方法在文檔中包含一個腳本呢? 該行的用途是什么:

w.addEventListener ? w.addEventListener("load", loader, false) :
                     w.attachEvent("onload", loader);

最后一點:我是JavaScript初學者,最后的(window, document)是什么?

第一個問題,代碼檢查是否定義了window.addEventListener 如果是,則使用它,否則使用window.attachEvent 這是為了瀏覽器兼容性。

第二個問題,這段代碼是一個匿名的 function,它有兩個參數,w 和 d。 這個 function 被立即調用,傳遞參數windowdocument

首先, w.addEventListener? 確定瀏覽器是否支持 window 的 addEventListener 方法

其次, (window, document)只是他在function(w,d) {}之前寫的匿名function的參數調用

以下 addEventListener 行用於注冊 function,以便在頁面完成加載時調用它。 Inte.net Explorer 和 Firefox(等)使用不同的函數來執行此操作。

w.addEventListener ? w.addEventListener("load", loader, false) :
                 w.attachEvent("onload", loader);

在 javascript 中,function 本身就是 object。 因此,它的“值”可以分配給變量或立即使用。 要立即使用它,必須將它括在括號中(否則它不會執行您想要的操作),然后像調用常規 function 一樣調用它。

(function (w, d) { ... }) (window, document);

如果我們把它分成兩條線,會更明顯。

var a = function(w, d){ ... };
a(window, document);

這樣做是為了不讓臨時值或函數污染全局 scope。 更不用說不要破壞其他任何變量。 這可以分為兩部分:

  1. 通過將代碼封裝在閉包中,任何明確聲明的內容都在閉包的 scope 中,而不是全局的 scope。var var loader在閉包的 scope 中。
  2. 通過立即使用閉包,它不會存儲在全局 scope 中的變量中。由於它是匿名聲明的,因此它不會作為命名 function 存在於全局 scope 中。

看起來作者在附加腳本標簽之前等待頁面完全加載。 addEventListener(DOM 級別 2)和 attachEvent(Microsoft 東西)是附加事件的更靈活的方式。 該代碼類似於說w.onload = loader

最后一點是將 arguments 傳遞給匿名的 function,其中它們被命名為wd 通過將 () 放在最后,立即調用匿名 function。

所以 function 被包裹在一個閉包中。 這反過來意味着w = windowd = document

當調用該方法時,它會創建一個名為onloadloader ,它是兩個可能的事件偵聽器觸發器之一的回調(意思是,當在窗口上調用load或加載事件時將調用它)。

x? y: z x? y: z語法是if then else call 的簡寫。

如果我們把它展開,它看起來像這樣:

if (w.addEventListener) {
  w.addEventListener("load", loader, false);
} else {
  w.attachEvent("onload", loader);
}

該語句用於滿足 IE 和其他瀏覽器的方法。

這實際上與以下內容相同:

function RegisterEventListener(w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    if (w.addEventListener) {
       w.addEventListener("load", loader, false);
    } else {
       w.attachEvent("onload", loader);
    }
}

RegisterEventListener(window, document);

唯一真正的區別是:

  1. 如果您定義匿名 function(使用function () {}; )而沒有將其分配給任何東西,則它僅供有限使用(因為無法引用它)。 同時,匿名函數還允許立即執行(就像你的問題function(a, b) {}(a, b);中的代碼一樣。
  2. condition? true: false condition? true: false (三級運算符)只是編寫簡單if語句的簡寫,因此它需要更少的輸入來寫出來,但有些人也認為它的可讀性較差。

我可能是錯的,但這是谷歌在他們的分析腳本中使用的實現。

這稱為閉包,即自動執行的 function 並將變量包含在其中,因此它們不會弄亂您的代碼。

這段代碼本質上是在它在文檔中找到的第一個腳本標簽之前創建一個腳本標簽和 append 到 DOM。

第一個問題的答案是關於瀏覽器兼容性的。 一些瀏覽器使用addEventListener和其他attachEvent將事件附加到頁面中的元素(在本例中為窗口),它會在 window 的加載事件上啟動(當所有內容加載完畢,文檔准備就緒后)。 看看這個以獲得更詳細的答案: window.onload vs $(document).ready()

第二個答案很簡單。 這是閉包(自動調用函數)中使用的參數,可以這樣讀取:

function anonymous(w, d) {
    ...
}
anonymous(window, document);

這段代碼的作者使用包裹在閉包中的匿名 function 來觸發注冊加載事件的 function。 在窗口的 onload 事件觸發之前,頁面上的腳本不會真正加載。

作者可能延遲腳本加載的原因可能是為了在實際加載其他腳本之前給 web 頁面更多時間來呈現。 這是一種很好的技術,可以快速加載頁面內容,同時延遲加載不是立即需要的資源。

作者使用的技術是一個包裹在閉包中的匿名 function。 想象一下:

myFunction (window, document);

現在,我將用匿名 function 替換 function 調用:

function(w, d) {
    // do stuff
    alert("w = " + w); 
    alert("d = " + d);
}

現在,我要讓 function 立即運行,而不實際給它命名。 我還將向匿名 function 傳遞兩個參數:

( function(w, d) {
      // do stuff
      alert("w = " + w);
      alert("d = " + d);
})  ("1234", "5678");

本例中的 output 為:

w = 1234
d = 5678

如果您觀察括號並將它們匹配起來,第一個外括號與最后一行字符 2 的右括號匹配,即 function 名稱,下面的一組括號將作為參數傳遞給 function 的兩個值包裝起來。

一開始這可能是一個很難掌握的概念; 在你看到它完成了幾次之后,它開始變得更有意義了。

  1. 以這種方式添加腳本允許作者將該腳本包含在文檔中而無需直接編輯 HTML 文件。 也可用於僅在需要時動態加載腳本。 (即,如果您有一堆代碼來編輯頁面上的某些內容,您不想在用戶實際單擊編輯按鈕之前下載它,這樣您就不會在不需要時浪費帶寬)。

  2. addEventListener 和 attachEvent 是在頁面加載完成時觸發調用 function 的方法。 在這種情況下,有一個名為 function 的loader兩者的原因是有些瀏覽器支持一個,有些瀏覽器支持另一個。 我使用 jQuery 的時間已經夠長了,以至於我不記得哪個是哪個了。

  3. (window, document) 是一種將這些變量封裝在 scope 和/或通過簡寫 w 和 d 引用它們的方法。 作者正在創建一個需要這些參數的 function,然后將 window 和文檔作為 arguments 傳遞給它們。

閉包還有助於作者避免他的腳本與頁面上的其他腳本發生沖突。 將其中聲明的每個變量想象成其他語言中的私有變量。

第一個代碼塊末尾的window, document是arguments到代碼塊rest中定義的匿名function。 由於 Javascript 幾乎是一種函數式語言,因此程序員可以定義這些匿名函數,甚至可以在不給它們命名的情況下使用它們。

您用問號粘貼的代碼塊是中綴表示法的示例,這是一種符合這種模式的語言結構: condition? ifTrueExpression: ifFalseExpression condition? ifTrueExpression: ifFalseExpression condition為真時,整個表達式將等於ifTrueExpression 否則,整個表達式將等於ifFalseExpression

您粘貼的中綴符號的使用在檢測正在使用哪種類型的 inte.net 瀏覽器時很常見。 雖然,我不確定這段代碼試圖檢測哪個瀏覽器,但它的目的是以瀏覽器特定的方式實現事件處理程序。

暫無
暫無

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

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