Javascript包装方法的区别

时间:2011-09-01 01:57:28

标签: javascript

通常认为Javascript代码应该包含在函数中,以防止泄漏到全局范围,只需将每个函数之外的任何内容分配给head对象(window在Web浏览器中)。

我在野外见过两种主要方法:

方法1:

(function() {
  // code here
}).call(this);

方法2:

(function() {
  // code here
})();

方法1 来自已编译的CoffeeScript代码,方法2 似乎是jQuery插件的首选样式:

jQuery的修改方法2:

(function($) {
  // JQuery Code
})(jQuery);

问题: 方法1 方法2 有什么区别? CoffeeScript喜欢专注于简洁,所以我认为CoffeeScript背后的人必须选择方法2 而不是方法1

3 个答案:

答案 0 :(得分:4)

他们非常不同。

方法1使用call,允许您更改函数内的this。例如:

(function() {
    alert(this); // DOMWindow
}).call(window);


var myObj = {a: 0};
(function() {
    alert(this); // Object => myObj {a: 0}
}).call(myObj);

要小心,因为您仍然可以使用这两种方法将内容转储到全局范围:

(function () {
    a = 5; // global
    var p = 10; // private to this function
})();

答案 1 :(得分:2)

方法一和二之间的区别取决于它们的使用环境。

与方法一一样,使用call执行函数将使用第一个参数作为“this” 功能。在方法二中,函数中的'this'将引用全局对象,因为调用尚未设置'this'(ES 5严格模式除外,它将是未定义的)。

掌握了这些知识,试着想一想如果这两个函数都放在要在浏览器中加载的JS文件的根目录中会发生什么。

在该上下文中,在方法一中传递给'call'的'this'将引用window对象,它是浏览器中的全局对象。方法二将完成同样的事情,因为调用未设置'this'的函数将 this 设置为全局对象(如上所述,在ES5严格模式下除外)。

因此,对于这种情况,他们会表现得一样。

但是,有些情况并非如此。

var obj = {
  f: function() {
    (function() {
      // 'this' here is 'obj' if called as obj.f()
    }).call(this);

    (function() {
      // 'this' not set by the call, defaults to 'window' (ES5 caveat)
    })();
  }
};

obj.f();

方法一是更清晰,因为它明确地传递了外部'this'的值,减少了混淆的可能性,并增加了灵活性。

如果“这个”无关紧要,方法二会更短更容易。

jQuery版本被用作一种总是能够通过'$'变量访问jQuery的简单方法,同时仍允许jQuery之外的代码具有$ mean其他内容。

答案 2 :(得分:0)

大多数时候没有区别。方法1显式设置'this'的值将在立即执行的函数内部。