使用 .call() 将 IIFE 的上下文更改为父作用域的 this 值。
第一个this 将是[object Window],这是浏览器 环境中的全局范围:
(function () {
console.log(this);
})();
第二个,将完全相同:
(function () {
console.log(this);
}).call(this);
不同之处在于,在 ECMAScript 5 的 strict mode 中,第一个示例 this 将是未定义的:
(function () {
'use strict';
console.log(this); // undefined
})();
但是,当使用严格模式和 .call() 时,这又是具有正确this 上下文的全局范围:
(function () {
'use strict';
console.log(this);
}).call(this);
Here's a jsFiddle 显示这个。主要区别在于normal IIFE 失去了它的this 上下文,一些CommonJS 平台评估具有特定this 的文件。
CoffeeScript 这样做是为了确保您的代码具有与放置它的范围(父范围)相同的 this 上下文 - 因为函数通常不会从周围的上下文继承其 this 对象。
使用上面的模式,你应该将你的函数逻辑包装在其中,以避免将所有代码放在全局范围内并发生变量/命名冲突,然后你可以创建诸如模块之类的东西并只返回您需要的 API,例如:
var Module = (function () {
'use strict';
return {
someMethod: function () {
// do something
}
}
})();
// call it:
Module.someMethod();
每个函数都会创建自己的作用域,因此将代码块包装在这些作用域中可以防止变量/函数名称相互冲突。我们还可以从这些闭包中访问“私有”方法:
var Module = (function () {
'use strict';
var _privateMethod = function () {};
return {
someMethod: function () {
_privateMethod();
}
}
})();
当我们不希望我们的用户也可以公开访问这些方法时,我们会这样做。