2015-07-21 91 views
-1

我剛剛通過此代碼here,它描述瞭如何在純js中創建自己的自定義就緒函數。答案是非常詳細的解釋,我一直在JS有一段時間了編程,但仍然有一個問題理解的代碼的起始部分,看看下面的代碼再次:​​瞭解如何調用ready函數中的匿名函數

(function(funcName, baseObj) { 
    // The public function name defaults to window.docReady 
    // but you can pass in your own object and own function name and those will be used 
    // if you want to put them in a different namespace 
    funcName = funcName || "docReady"; 
    baseObj = baseObj || window; 
    var readyList = []; 
    var readyFired = false; 
    var readyEventHandlersInstalled = false; 

    // call this when the document is ready 
    // this function protects itself against being called more than once 
    function ready() { 
     if (!readyFired) { 
      // this must be set to true before we start calling callbacks 
      readyFired = true; 
      for (var i = 0; i < readyList.length; i++) { 
       // if a callback here happens to add new ready handlers, 
       // the docReady() function will see that it already fired 
       // and will schedule the callback to run right after 
       // this event loop finishes so all handlers will still execute 
       // in order and no new ones will be added to the readyList 
       // while we are processing the list 
       readyList[i].fn.call(window, readyList[i].ctx); 
      } 
      // allow any closures held by these functions to free 
      readyList = []; 
     } 
    } 

    function readyStateChange() { 
     if (document.readyState === "complete") { 
      ready(); 
     } 
    } 

    // This is the one public interface 
    // docReady(fn, context); 
    // the context argument is optional - if present, it will be passed 
    // as an argument to the callback 
    baseObj[funcName] = function(callback, context) { 
     // if ready has already fired, then just schedule the callback 
     // to fire asynchronously, but right away 
     if (readyFired) { 
      setTimeout(function() {callback(context);}, 1); 
      return; 
     } else { 
      // add the function and context to the list 
      readyList.push({fn: callback, ctx: context}); 
     } 
     // if document already ready to go, schedule the ready function to run 
     if (document.readyState === "complete") { 
      setTimeout(ready, 1); 
     } else if (!readyEventHandlersInstalled) { 
      // otherwise if we don't have event handlers installed, install them 
      if (document.addEventListener) { 
       // first choice is DOMContentLoaded event 
       document.addEventListener("DOMContentLoaded", ready, false); 
       // backup is window load event 
       window.addEventListener("load", ready, false); 
      } else { 
       // must be IE 
       document.attachEvent("onreadystatechange", readyStateChange); 
       window.attachEvent("onload", ready); 
      } 
      readyEventHandlersInstalled = true; 
     } 
    }; 
})("docReady", window); 

和我我打電話的代碼是這樣的:

docReady(function() { 
     alert('hello'); 
    }, window); 

我的問題是,你怎麼能調用一個匿名函數,像這樣? ..我完全糊塗了:(

如何在地球上,即使下面的代碼工作

docReady(function() { 
     alert('hello'); 
    }, window); 

我的意思是沒有定義明確的docReady功能,像這樣:

docReady function (param1, param2); 

所有我看到docReady作爲參數傳遞給匿名函數?

+1

'baseObj [funcName]'聲明函數(編輯:我做了一個答案使其更清晰)。 –

+1

他說什麼。在上面的代碼中,'baseObj'是'window','funcName'是''docReady'',所以它是'window [「docReady」] = function()...',它與window相同。 docReady = function()...' –

回答

3
baseObj[funcName] = function(callback, context) { 

相當於

window["docReady"] = function(callback, context) { 

它定義了功能的window屬性,全局對象,這意味着你可以用

window["docReady"](function() { 
    alert('hello'); 
}, window); 

或稱之爲

window.docReady(function() { 
    alert('hello'); 
}, window); 

甚至

docReady(function() { 
     alert('hello'); 
}, window); 

作爲全局對象的屬性也是全局作用域的變量(以及直到被映射的內部的任何作用域)。

+0

!!喔!謝謝 ! –

2

的關鍵位是baseObj[funcName] = function

在這一點上是baseObj(或至少可以)window,並funcName是(或可以是)docReady

所以在這一點上它增加了一個功能,window(全球)被稱爲「docReady」

window和「docReady」被作爲默認參數傳遞的最後一行

})("docReady", window);

這在頂部輸入功能作爲參數(function(funcName, baseObj) {

NB當我說baseObj是(或至少可以)window,那是因爲你可以重寫此值,則該行:如果一個另類心不是提供

funcName = funcName || "docReady"; 
baseObj = baseObj || window; 

集的funcName爲「docReady」和baseObj,這意味着如果你喜歡,你可以改變他們,所以如果最後一行改爲})("getReady", myObject);的功能將被稱爲GETREADY並加入到myObject,而不是全球window

0

您正在閱讀的代碼錯誤。

檢查這些行:

(function(funcName, baseObj) { 
    ... 
    baseObj[funcName] = function(callback, context) { 
     ... 
    }; 
    ... 
})("docReady", window); 

它添加新的屬性爲baseObj,在這種情況下是window。該屬性是您所調用的功能。 docReady。一切都是全球性的,不需要被稱爲window.something。這就是爲什麼你使用docReady