[英]node.js: Confusing usage of 'this' in the global scope
我最近一直在玩弄的node.js,我跑成左右的使用一个怪异的行为this
在模块的全局范围。
this
绑定到全局范围内的module.exports:
console.log(this === exports); // -> true
但是this
在方法范围内必然是全局的:
(function() { console.log(this === global); })(); // -> true
这也导致了这种令人困惑的行为:
this.Foo = "Weird";
console.log(Foo); // -> throws undefined
(function() { this.Bar = "Weird"; })();
console.log(Bar); // -> "Weird"
我想,解决的办法就是从来不使用this
在全球范围内,并明确使用extends
或global
代替,但有这一切背后的逻辑还是在node.js中的错误或限制?
在“逻辑”的背后也就是值this
总是取决于函数是如何调用 。
在您的情况下,您有一个自执行的匿名函数,在那里, this
总是引用全局对象(非严格模式)或undefined
(ES5严格)。
如果要访问“外部” this
值,可以在执行该函数之前存储引用,例如
var outerScope = this;
(function() { outerScope.Bar = "Weird"; })();
console.log(Foo); // -> throws undefined
或者重新.bind()
函数范围,比如
(function() { this.Bar = "Weird"; }).bind(this)();
在处理简单的CommonJS模块实现时,我不得不考虑在模块的全局范围内如何处理this
; 规范没有解决这个问题。
我最初也将它设置为exports
对象,因为我认为这会很有用,但后来发现了一些代码,我需要“模块化”使用this
来获取全局对象的句柄,所以我把this
改成了全局对象,为模块代码提供尽可能“正常”的环境。
我们只能猜测为什么节点的设置方式(或询问作者),但我的猜测只是因为它似乎是一个有用的想法,类似于你给module
对象一个exports
属性的方式在节点中并将其反映在模块的实际exports
(此行为也不是规范的一部分,但也不反对它)。
至于你提到的问题的一部分this
参考global
的功能,其他的答案解释,这只是方式this
作品; 它不是特定于节点的行为,它是一种奇怪的JavaScript行为。
我不知道这是否是Node.js团队的确切意图,但如果不是,我会感到惊讶。 考虑这个示例在浏览器的开发控制台中运行(例如chrome):
var x = function(){console.log(this)}
a = {}
a.x = x
a.xx = function(){x()}
a.x()
>> Object
a.xx()
>> DOMWindow
x()
>> DOMWindow
正如您所看到的,在不指定其上下文的情况下执行方法会将上下文设置为全局上下文。 在这种情况下是DOMWindow对象。
当您在模块中时,您的上下文是模块,但在其中执行方法而不指定.call或.apply或obj的上下文。 将利用全球范围内, global
,而不是当地的一个, module.exports
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.