代码之家  ›  专栏  ›  技术社区  ›  dkinzer

这个javascript/jquery语法是如何工作的:(函数(窗口,未定义))(窗口)?

  •  152
  • dkinzer  · 技术社区  · 15 年前

    你有没有看过引擎盖下面 jQuery 1.4 源代码并注意到它是如何以以下方式封装的:

    (function( window, undefined ) {
    
      //All the JQuery code here 
      ...
    
    })(window);
    

    我读过一篇关于 JavaScript Namespacing 还有一个叫 An Important Pair of Parens 所以我知道这里发生了什么。

    但我以前从未见过这种特殊的语法。那是什么 undefined 在那里干什么?为什么? window 需要通过然后再次出现在末尾?

    5 回复  |  直到 8 年前
        1
  •  157
  •   Kara Praveen Prasad    11 年前

    未定义是一个正态变量,可以简单地用 undefined = "new value"; . 所以jquery创建了一个真正未定义的本地“未定义”变量。

    由于性能原因,窗口变量被设置为本地变量。因为当javascript查找变量时,它首先遍历局部变量,直到找到变量名。当找不到它时,javascript将进入下一个作用域等,直到它过滤掉全局变量。因此,如果将窗口变量设为本地变量,则javascript可以更快地查找它。 更多信息: Speed Up Your JavaScript - Nicholas C. Zakas

        2
  •  53
  •   David Tang    14 年前

    未定义

    通过声明 undefined 作为一个参数,但从不向其传递值,这样可以确保它始终是未定义的,因为它只是全局范围中可以被覆盖的一个变量。这使得 a === undefined 安全的替代品 typeof a == 'undefined' ,这将保存几个字符。它还使代码更小型化,如 未定义 可以缩短为 u 例如,再保存几个字符。

    窗口

    经过 window 作为参数,在本地作用域中保留一个副本,这会影响性能: http://jsperf.com/short-scope . 所有访问 窗口 现在必须在范围链上减少一个级别。和一样 未定义 ,本地副本再次允许更积极的缩小。


    司扥噢特:

    尽管这可能不是jquery开发人员的意图,但是传递 窗口 例如,允许库更容易地集成到服务器端的JavaScript环境中。 node.js -没有全球性的 窗口 对象。在这种情况下,只需更改一行即可替换 窗口 对象与另一个对象。对于jquery,模拟 窗口 可以创建和传递对象,以便进行HTML擦除(例如 jsdom 可以做到这一点。

        3
  •  16
  •   Chetan S    15 年前

    其他人已经解释了 undefined . 未定义 就像一个全局变量,可以重新定义为任何值。这种技术是为了防止所有未定义的检查被破坏,如果有人写了这样的话, undefined = 10 某处。一个从未被通过的论点肯定是真实的。 未定义 无论 变量 未定义 .

    通过以下示例可以说明通过窗口的原因。

    (function() {
       console.log(window);
       ...
       ...
       ...
       var window = 10;
    })();
    

    控制台记录什么?价值 window 对象权?错了!10?错了!它日志 未定义 . javascript解释器(或jit编译器)以这种方式重写它-

    (function() {
       var window; //and every other var in this function
    
       console.log(window);
       ...
       ...
       ...
       window = 10;
    
    })();
    

    但是,如果你得到 窗口 变量作为一个参数,没有变量,因此没有惊喜。

    我不知道jquery是否在这样做,但如果您正在重新定义 窗口 函数中任何地方的局部变量,无论出于什么原因,最好从全局范围借用它。

        4
  •  6
  •   Nick Craver    15 年前

    window 就像这样传入,以防有人决定在IE中重新定义窗口对象,我假定 undefined 以防以后以某种方式重新分配。

    顶部 窗口 在该脚本中,只是将参数命名为“window”,该参数比全局参数更为本地 窗口 引用以及这个闭包内的代码将使用什么。这个 窗口 最后是指定第一个参数要传递的内容,在本例中是 窗口 …希望你没有搞砸 窗口 在那之前。

    通过显示jquery插件中使用的最典型的情况,这可能更容易理解。 .noConflict() 处理,因此对于大多数代码,您仍然可以使用 $ 即使这意味着什么 其他 jQuery 超出此范围:

    (function($) {
      //inside here, $ == jQuery, it was passed as the first argument
    })(jQuery);
    
        5
  •  5
  •   Semra    13 年前

    用1000000次迭代进行测试。这种本地化对性能没有影响。在1000000次迭代中甚至没有一毫秒。这根本没用。