使用以下习惯用法定义 CommonJS 模块是很常见的:
(function() {
var logThis = function() { console.log(this); }
module.exports = logThis;
}).call(this);
我只花了半个小时和一位同事讨论他们为什么用call(this)
. 这将导致this
闭包内部的值从调用者继承,而不是设置为全局对象。但是,当我在 Node.js 中对此进行测试时,this
模块内部的值始终是全局对象,即使我像这样加载并运行它:
var bar = {};
bar.foo = function() { var foo = require("./foo"); foo(); }
我真的希望bar
在控制台中看到该对象,但实际上我看到的是全局对象。然后我想到这可能是因为像 Underscore.js 这样的模块也用于 Web 上下文。但在那种情况下,它会被加载一个 <script> 标签,所以无论如何它this
总是等于全局对象。
是什么赋予了?我确信使用这种结构是有原因的,但在这种特殊情况下,无论模块是在 Node.js 中还是在网页中使用,我都看不出实际的区别。
更新:为了澄清,我可以想到一些可能会产生影响的情况。例如,如果我说:
var bar = {}
var foo = require("./foo");
bar.foo = foo;
bar.foo();
(感谢@Pointy 纠正我原来的例子。)
我希望模块中的闭包在require()
被调用时被评估,这意味着它this
内部的值将绑定到全局对象,即使foo()
随后作为“bar”的成员调用,也会将其写入控制台“ 目的。但是,即使在此示例中,我也会在控制台中看到“栏”对象。我想这this
并没有像我预期的那样被关闭?
简而言之,我正在寻找一个示例,其中像 Underscore.js 这样的模块将具有不同的行为,因为它被包装在一个调用的闭包中,fn.call(this)
而不是只是fn()
在 Node.js 或网页中。