Javascript:此代码有什么作用?

mel*_*oon 7 javascript jquery

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

在使用JS多年之后,我今天决定真正开始学习JS的工作原理,而不是像在浏览器中运行的那样对待它.所以我开始深入研究jQuery代码,看看真正的JS开发人员如何使用langauge.就在那时我发现了一段看起来像下面代码的代码.注意,我把这个代码从另一个堆叠的帖子中删除了这里在Javascript中,你能扩展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
})();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

更新

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

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

console.log(MyDomConstruct('foo'))
Run Code Online (Sandbox Code Playgroud)

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

return new MyDomConstruct(elems);
Run Code Online (Sandbox Code Playgroud)

如果声明像这样,我可以理解明确返回"this"

return MyDomConstruct(elems);
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.

jAn*_*ndy 9

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

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

(function($){
}(jQuery));
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

var mytest = myDOM([]);
Run Code Online (Sandbox Code Playgroud)

你将无法访问MyDOMConstruct,但你的内部功能确实有权访问.这样你就可以保护你的方法和变量.它也被称为method pattern.在这种情况下总是很好的阅读Douglas Crockford: Javascript the good parts.

为什么明确地返回"这个"?这本来是自动完成的,对吗?

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

mytest.forEach([]).addStyles([]); ...
Run Code Online (Sandbox Code Playgroud)

因为在这种情况下,每个方法都返回调用对象myDOM.

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

我希望在这一点上应该清楚.

编辑

根据您的更新:

new MyDOMConstruct();
Run Code Online (Sandbox Code Playgroud)

生成一个inherits来自的新对象

MyDOMConstruct.prototype
Run Code Online (Sandbox Code Playgroud)

如果没有new keywordthis不会被绑定到新的对象.相反,它将绑定到全局对象(窗口),您将使用this.


Pet*_*tai 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 ().
Run Code Online (Sandbox Code Playgroud)


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.
Run Code Online (Sandbox Code Playgroud)

所以内部对象可以被命名为任何东西,并且它可以被执行myDOM(),但是如果你命名内部函数blah,你仍然可以通过使用myDOM()...来执行它...这不是很清楚...更好地命名它.

3.为什么明确地返回"这个"?这本来是自动完成的,对吗?

不,如果你不写任何东西,Javascript会自动返回undefined.该MDC参考:.

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