2015-07-21 107 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