zoukankan      html  css  js  c++  java
  • jquery 中 (function( window, undefined ) {})(window)写法详解(转)

    最常见的闭包 (Closure) 范式大家都很熟悉了:

    123 (function() {// ...})();

    很简单,大家都在用。但是,我们需要了解更多。
    首先,闭包是一个匿名函数 (Anonymous function), 即是 (function() {}) 这部分。之所以要给 function 添加括弧是为了让它形成一个表达式 (expression), 有了表达式,并且确定它的类型是个函数 (Function 实例), 就可以直接调用它。所以,后面的一对括弧是可以工作的,它的意义是:我要调用 (call) 这个函数。

    既然是函数调用,那就可以像一般的函数那样,在调用时传入参数。这就是本次讨论的话题。

    传入 window 参数

    123 (function(win) {// ...})(window);

    这样做最直观的好处是书写便利:少写几个字。你可以在闭包内任何地方使用 win, 它都会指向 window 对象。另外,它有利于压缩减少最终代码的体积,经过压缩后 (如 Google Closure Complier), 所有的 win 都会被替换成形如 a 这样的简单变量。win 用得越多,减少的字节数也越多。

    不过,便利的同时也会带来陷阱。在 IE 上,window 总是指向当前窗口对象,这个没有问题,但是在某些场景下,使用闭包内的 win 变量会导致拒绝访问错误 (Access denied). 重现方式大致是这样的:当页面引用其他域名的脚本,并且该脚本调用了闭包内的 window.document, 而且这个闭包代码是来自另一个域名的脚本。在这种情况下,使用 win 会保持对 window 最早的引用,通过另一个域的脚本访问 win 会导致 IE 认为脚本产生了跨越冲突,从而拒绝了对 win.document 的访问。解决办法是不使用形参 win, 而是直接使用 window. 需要说明的是,给闭包传入 document 也会导致 IE 出现同样的问题。

    传入 undefined

    其实把 undefined 作为形参就,实参就可以不用传了,因为 JavaScript 中访问未传入的参数就会得到 undefined. 因此,你可以这样写:

    123 (function(undefined) {// ...})();

    和上面的讨论一样,你可以在闭包内任何地方使用 undefined, 可以少写几个字(如果把 undefined 换成更短的名字),也可以在减少压缩后体积。

    另一个的优势是,你可以认为它是个变量,把它当变量来使用,它的值恒等于 (===) 真正的 undefined. 当外部代码意外地定义了 undefined 的时候——不常见,但确实可能会发生——你可以正常地使用真正的 undefined, 而不会被外部的 undefined 意外影响. 这是由 JavaScript 作用域规则决定的。
    无论是否使用这个 undefined 参数,都应该避免使用 undefined 的字符串常量,如:

    123 if(typeofmyVar === 'undefined') {// bad part...}

    因为如果你把字符串写错了,机器不会告诉你,而且会产生一个难以检查出来的bug. 幸运的是,对于 JavaScript 来说,JsLint 可以帮你做这个校验。当 myVar 已定义的时候(通过形参或 var 声明),上面的代码改成这样会更易于调试:

    123 if(myVar === undefined) {// good part...}

    结论

    从上面两个例子来看,我们建议不要传入 window, 但是可以安全地使用第二种方式 (写 undefined 形参);我们还要尽量避免使用字符串常量。

    因此,在jquery中经常会将$.extend()和$.fn.extend()放到类似于上面的写法中,即(function($,undefined))(jQuery)。那么内部的$都指向jQyery。

     -----------------

    (function(undefined){
         //do something
    })() //1  


    在闭包行参使用undefined而不是从外部1处传入参数,这样做是考虑到在undefined在外部被赋值情况,那么这时候在闭包内部使用undefined就会出现问题了,那么就需要 

    if(typeof undefined === 'undefined') {
    // 
    }  17jquery.com 

    判断。在外部不传参数情况下,闭包内部使用形参在没有赋值时undefined将会保持原本含义,这是由JavaScript 作用域规则决定。 
    为了不让内部的undefined不会被污染,在形参中默认加上undefined,所以在jquery等js库源代码会看到 

    (function(window,undefined){
       //todo something
    })()  


    这样代码。在形参中传入默认window也是;类似一样的原理。 

    最后可以测试下: 

    var undefined = 123;
    (function(undefined){
      console.info(undefined);
    })() //在参数中传入undefined和不传情况下会输出什么?  
  • 相关阅读:
    LG2664 树上游戏
    「NOI2007」 货币兑换
    「NOI2012」骑行川藏
    LG4721 【模板】分治 FFT
    LG4783 【模板】矩阵求逆
    test20181019 B君的第二题
    LOJ129 Lyndon 分解
    「NOI2017」泳池
    LG4723 【模板】常系数线性递推
    「AHOI / HNOI2017」礼物
  • 原文地址:https://www.cnblogs.com/youxin/p/3406866.html
Copyright © 2011-2022 走看看