内联函数调用有什么好处?

12

我看到了这段代码(明确地说,这是jQuery的代码,并进行了修改)

(function(window,undefined){
    var jQuery=(function(){
        var jQuery=something;
        jQuery.xxx=xxx;
        //...
        return jQuery;
    })();
    //...
    window.jQuery=window.$=jQuery;
})(window);
虽然我理解将代码包装在内联函数调用中可以清晰地定义变量作用域,但我不明白以下内容的好处:
1.传递带参数的window而不是直接使用它, 2.通过未定义的参数获取undefined实例,以及 3.通过另一个内联函数调用的返回值来定义jQuery
可以有人解释一下吗?
编辑#3更清楚地写道: 我的理解是,该代码在另一个函数内定义jQuery,然后返回它。
//(function(window,undefined){
var jQuery=(function(){
    // Inside this function defines jQuery and return it?
    var jQuery=function(selector,context){
        return new jQuery(selector,context); //simplified
    };
    jQuery.xxx=xxx;
    //...
    return jQuery;
})(); // This executes the inline function and assign `jQuery` with the return value???
//... })(window);

这更像是以下内容:

function define_jQuery(){
    // Inside this function defines jQuery and return it?
    var jQuery=function(selector,context){
        return new jQuery(selector,context); //simplified
    };
    jQuery.xxx=xxx;
    //...
    return jQuery;
}

//(function(window,undefined){
var jQuery=define_jQuery(); // This executes the inline function and assign `jQuery` with the return value???
//... })(window);

是否更简单的做法是:

//(function(window,undefined){
var jQuery=function(selector,context){
    return new jQuery(selector,context); //simplified
};
jQuery.xxx=xxx;
//...
//... })(window);

1
嗨,http://ejohn.org/apps/workshop/adv-talk/#31 和 http://www.bennadel.com/blog/1838-Wrapping-The-Window-Object-In-A-jQuery-Wrapper.htm 这两个链接应该会有所帮助!:) - Tats_innit
4个回答

10

回答这些问题:

  1. 为什么要传入 window?因为在 JavaScript 中解引用变量很痛苦。传入一个实例意味着你不必这样做。通常的机制是这样的:

  2. (function (window, document, $) {
    }(window, window.document, jQuery));
    

    在这种情况下,不需要转到全局范围来引用这三个变量(而且jQuery可以使用.noConflict())。

  3. 这是有效的JavaScript:undefined = 2;。我承认这很愚蠢,但是确实是可能的。但是,如果在函数中接受的参数个数比传递的参数个数多一个,那么可以确信它是真正的undefined,而不是被篡改过的。

  4. 从前一个函数返回jQuery允许方法链接:$('#sel').func1().func2()。这是可能的,因为func1大概长成这样:

    jQuery.fn.func1 = function () {
        return $(this).each(function () {
            // do something fabulous
        };
    };
    

    return $(this).bla_de_bla() 的简写形式是:

        $(this).bla_de_bla(..);
        return $(this);
    
    它还假定.bla_de_bla()也返回$(this)。
    编辑:修改第三点以指出它最擅长链接而不是绕过.noConflict()和错误命名的$。

我已经重写了第三条,让它更清晰明了,你可以检查一下吗? - Alvin Wong
里面有一些非常神秘的事情,还有一些比我们聪明的人在做。我从来没有像他们那样需要嵌套jQuery定义,浏览你刚刚引用的代码确实让我眯起了眼睛。其中一些jQuery是指向“原始jQuery”的指针(以防您之前定义过它),一些是指向“我们正在构建的jQuery”,一些是指向“您所选择的内容”。其他一切都相等的情况下,我宁愿它们有更具描述性的名称。唯一真正优雅的事情是jQuery.fn缩写为jQuery.prototype - robrich

1

一个原因是为了代码缩小。缩小器无法缩小全局名称,因为它们不再引用全局对象。通过传递您正在使用的所有对象,它们变成本地对象。这样,对于windowundefined的数千个引用可以被缩小。


0
window作为参数传递实际上什么也不做,只是浪费空间:它是一个对象,因此通过引用传递。在闭包内部对window进行的任何更改都会影响外部相同的实例。
获取undefined参数是针对那些愚蠢到给一个实际变量命名为undefined(在新版本的浏览器中无法这样做)的人的一种防范措施。
据我所知,第二个内联函数完全没有意义,除非在定义jQuery属性的过程中使用了临时变量。

0

"window"参数的美妙之处在于它不需要解除引用。如果您在一个实例中传递了"window",而在另一个实例中传递了window.parent(考虑子窗口控制父窗口以进行高级功能),那会怎么样!!!

  1. 如上所述。

  2. 我还不太确定。

  3. 链接!例如:$('#blah').hide().show();

如果hide函数没有将对象(#blah)返回,show就无法对其执行任何操作!它将#blah返回给show函数。

JQuery总是比我聪明一点(而我通常会找到隐藏的线索!)。


我已经重新修改了第三个,使其更加清晰,你能否请检查一下? - Alvin Wong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接