Javascript:此代码有什么作用?

时间:2010-10-21 06:09:10

标签: javascript jquery

如果这个问题过于宽泛,我会提前道歉。事实上,这是4个不同的问题,但都与相同的代码相关,我认为它们都围绕着相同的原则。

我今天决定使用JS多年后,实际上开始学习JS如何工作,而不是像在浏览器中运行的那样对待它。所以我开始深入研究jQuery代码,看看真正的JS开发人员如何使用langauge。就在那时我发现了一段看起来像下面代码的代码。请注意,我将此代码从此处的另一个堆叠帖子In Javascript, can you extend the DOM?中删除。所以这并不意味着编写此代码的人甚至不知道他在说什么。

var myDOM = (function(){ // #1
    var myDOM = function(elems){ // #2
            return new MyDOMConstruct(elems);
        },
        MyDOMConstruct = function(elems) {
            this.collection = elems[1] ? Array.prototype.slice.call(elems) : [elems];
            return this; // #3
        };
    myDOM.fn = MyDOMConstruct.prototype = {
        forEach : function(fn) {
            var elems = this.collection;
            for (var i = 0, l = elems.length; i < l; i++) {
                fn( elems[i], i );
            }
            return this;
        },
        addStyles : function(styles) {
            var elems = this.collection;
            for (var i = 0, l = elems.length; i < l; i++) {
                for (var prop in styles) {
                    elems[i].style[prop] = styles[prop];
                }
            }
            return this;
        }
    };
    return myDOM; // #4
})();

1为什么使用var myDOM =(function(){})()声明函数;而不是var myDOM = function(){};

2为什么在myDOM函数中使用完全相同的名称声明另一个函数?为什么不将所有内部myDOM的逻辑放在外部myDOM函数中?

3为什么明确地返回“this”?这本来是自动完成的,对吗?

4这里发生了什么?它是否返回内部myDOM的构造函数?如果是这样,为什么?

更新

所以现在大部分都有意义。关于#1,我认为myDOM被分配了=之后定义的函数,但事实并非如此。它被分配给函数返回的任何东西。这恰好是一个功能。

我还不清楚#3。是的,我理解使用像这样的功能

console.log(MyDomConstruct('foo'))

会显示'undefined'。但这不是它的使用方式。这几行是

return new MyDomConstruct(elems);

如果语句像这样

,我可以理解明确返回“this”
return MyDomConstruct(elems);

但事实并非如此。

5 个答案:

答案 0 :(得分:9)

为什么使用var myDOM =(function(){})()声明函数;而不是var myDOM = function(){};

这就是所谓的self-invoking anonymous functionself-executing anonymous function。它就是这样,它在运行时调用它自己。你还会看到模式:

(function($){
}(jQuery));

在jQuery世界中非常多。同样的事情是,在运行时函数调用自身并保证$符号在函数体中具有对jQuery对象的引用。

在你的代码片段中,函数调用自身并返回myDOM函数引用。

为什么要使用完全相同的名称在myDOM函数中声明另一个函数?为什么不将所有内部myDOM的逻辑放在外部myDOM函数中?

这只是一个惯例。它可以被称为任何你想要的,也许作者认为这样做很方便。这种模式的原因是隐私和安全。通过返回内部myDOM引用,将创建closure。所以后面声明了像

这样的东西
var mytest = myDOM([]);

您将无法访问MyDOMConstruct,但您的内部功能确实可以访问。这样你就可以保护你的方法和变量。它也被称为method pattern。在此上下文中始终是一个很好的阅读Douglas Crockford: Javascript the good parts

为什么要明确返回“this”?这本来是自动完成的,对吗?

不,函数默认会返回undefined值。通过显式返回this,您可以chain方法(来自上面的示例调用):

mytest.forEach([]).addStyles([]); ...

因为每个方法都返回调用对象,在本例中为myDOM

这里发生了什么?它是否返回内部myDOM的构造函数?如果是这样,为什么?

我希望此时应该清楚。

修改

根据您的更新:

new MyDOMConstruct();

从{/ p>生成inherits的新对象

MyDOMConstruct.prototype

如果没有new keywordthis将不会绑定到新对象。相反,它将绑定到全局对象(窗口),您将使用this访问全局变量。

答案 1 :(得分:6)

<强> 1。为什么使用var myDOM = (function() {})();而不是var myDOM = function() {};

来声明函数

使用的表单是自执行功能。这意味着myDOM设置为函数返回的任何值。第二种形式将myDOM设置为函数,但不立即执行该函数。

var myDOM = (function() {           // <== This is a function that does something
                // Something
            })();                 // The function is executed right HERE with ().


<强> 2。为什么要使用完全相同的名称在myDOM函数中声明另一个函数?为什么不将所有内部myDOM的逻辑放在外部myDOM函数中?

因为你在最后返回内部myDOM函数....所以命名实际上是有意义的,尽管它最初是令人困惑的。这通常用于在JS中创建私有变量。由于内部函数可以访问作用域(自执行匿名函数),但用户不会。

var myDOM = (function() {  // <== This is a function that is going to return 
                           // a function / object
                var myDOM = function() { // <== We're going to return this
                    ...                  //     The outer myDom will be set to it
                };                       //     So it's actually helpful to name
                                         //     it the same for clarity.
                return myDOM;
            })();

// Now we can access that inner object by using the outer myDOM.
// We could access the inner object using myDOM even if the inner object
//   was named otherTHING... It's confusing to acces something
//   called otherTHING in the code by
//   writing myDOM().... so better name the inner returned function
//   myDOM as well.

因此内部对象可以被命名为任何内容,并且可以使用myDOM()执行,但是如果您命名内部函数blah,您仍然可以使用myDOM()执行它。 ..那不是很清楚......更好地命名它。

第3。为什么明确地返回“这个”?这本来是自动完成的,对吗?

不,如果您不写任何内容,Javascript会自动返回undefined MDC reference:

返回this通常用于保留方法的上下文。它曾经使方法($(here).is().a().chain().of().methods())的链接成为可能。因此链中的方法知道它正在运行的上下文。

答案 2 :(得分:3)

自动执行的匿名函数再说一句。在(function() { })();块中包装一些JavaScript是一种创建私有命名空间的方法。除了返回的值(在本例中为myDOM)之外,您在内部函数中执行的所有操作都将是私有函数。

那就是你可以拯救地做像

这样的事情
var counter = (function() {
   var i = 0;
   var counter = function() {
      alert(i++);
      return i;
   }
   return counter;
})();

counter(); // will alert 0
counter(); // will alert 1
// ... and so on

从函数外部保留一些内部状态机密。第二个原因,如其他帖子中所述,它不会使用变量i污染全局命名空间。这就是为什么最好在jQuery插件开发中使用这些函数的原因。

答案 3 :(得分:1)

与此相同:


(function () {
    function b(a) {
        return new c(a)
    }
    function c(a) {
        this.a = a[1] ? Array.prototype.slice.call(a) : [a];
        return this
    }
    b.b = c.prototype = {};
    return b
})();

希望有帮助......:)

答案 4 :(得分:1)

例如: var fn =(function(){    return function(){alert(11)}; })(); 当代码运行时,现在fn = function(){alert(11)}; 试试吧!!!