通常认为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 。
答案 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'的值将在立即执行的函数内部。