Jef*_*Cyr 10 javascript node.js
我最近一直在玩node.js而且我遇到了关于this模块全局范围内使用的奇怪行为.
this 绑定到全局范围中的module.exports:
console.log(this === exports); // -> true
Run Code Online (Sandbox Code Playgroud)
但是this在方法范围内绑定到全局:
(function() { console.log(this === global); })(); // -> true
Run Code Online (Sandbox Code Playgroud)
这也导致了这种令人困惑的行为:
this.Foo = "Weird";
console.log(Foo); // -> throws undefined
(function() { this.Bar = "Weird"; })();
console.log(Bar); // -> "Weird"
Run Code Online (Sandbox Code Playgroud)
我想解决方案是永远不要this在全局范围内使用并明确使用extends或global替代,但是这背后是否存在逻辑,或者它是node.js中的错误或限制?
其背后的"逻辑"是,值this始终取决于函数的调用方式.
在您的情况下,您有一个自执行的匿名函数,在那里,this始终引用全局对象(非严格模式)或undefined(ES5严格).
如果要访问"外部" this值,可以在执行该函数之前存储引用,例如
var outerScope = this;
(function() { outerScope.Bar = "Weird"; })();
console.log(Foo); // -> throws undefined
Run Code Online (Sandbox Code Playgroud)
或者重新.bind()定义自己的功能范围
(function() { this.Bar = "Weird"; }).bind(this)();
Run Code Online (Sandbox Code Playgroud)
this在开发一个简单的 CommonJS 模块实现时,我必须考虑在模块的全局范围内做什么;规范中没有解决这个问题。
我一开始也将它设置为exports对象,因为我认为这会很有用,但后来发现我需要“模块化”一些代码this,这些代码用于获取全局对象的句柄,所以我改this回全局对象为模块代码提供尽可能接近“正常”的环境。
我们只能猜测为什么节点会这样设置(或者询问作者),但我的猜测是这样做只是因为这似乎是一个有用的想法,类似于您可以在节点中为module对象提供属性的方式exports并将其反映在模块的实际中exports(这种行为也不是规范的一部分,但也不违反规范)。
至于你的问题中关于函数this引用的部分global,正如其他答案所解释的那样,这就是有效的方法this;这不是特定于节点的行为,而是一种奇怪的 JavaScript 行为。
| 归档时间: |
|
| 查看次数: |
254 次 |
| 最近记录: |