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

时间:2012-07-03 04:39:28

标签: javascript jquery

我看到了这段代码(显然它是在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。 有人可以解释一下吗?

  4. 编辑更清楚地写出#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);
    

4 个答案:

答案 0 :(得分:10)

分别回答这些问题:

  1. 为什么window传入?因为在JavaScript中解除引用变量是很痛苦的。传递实例意味着您没有必要。通常,该机制如下所示:

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

    在这种情况下,不需要去全局范围来取消引用这三个中的任何一个(并且jQuery可以在.noConflict()中启动)。

  2. 这是有效的JavaScript:undefined = 2;。我承认这是非常愚蠢的,但这是可能的。但是如果一个函数在一个函数中再接受一个参数而不是一个函数,那么人们就会确信它是undefined而不是一个被黑的副本。

  3. 从前一个函数返回jQuery允许方法链接:$('#sel').func1().func2()。这是可能的,因为func1可能看起来像这样:

    jQuery.fn.func1 = function () {
        return $(this).each(function () {
            // do something fabulous
        };
    };
    
  4. return $(this).bla_de_bla()简写:

        $(this).bla_de_bla(..);
        return $(this);
    

    它还假设.bla_de_bla()也返回$(this)

    编辑:修改了#3,注意最好是链接而不是环绕.noConflict()并错误地命名$

答案 1 :(得分:1)

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

答案 2 :(得分:0)

window作为参数传递确实可以完全消除所有错误并浪费空间:它是一个对象,因此通过引用传递。对闭包内window的任何更改都会影响与外部相同的实例。

获取undefined参数是对任何愚蠢到足以命名实际变量undefined的人的对策(无论如何你都无法在新的浏览器中做到这一点)

据我所知,第二个内联函数完全没有意义,除非在定义jQuery属性的过程中使用了临时变量。

答案 3 :(得分:0)

关于“窗口”参数的美丽部分不是解除引用。如果你在一个实例中传入“window”而在另一个实例中传递window.parent会怎么样(想想控制父项的子窗口以获得提前功能,呃!!!)。

  1. 如上所述。

  2. 我还不太确定。

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

  4. 如果隐藏功能没有返回对象(#blah),show就无法执行任何操作!它将#blah归还给show函数。

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