繁体   English   中英

node.js:在全局范围中混淆使用'this'

[英]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在全球范围内,并明确使用extendsglobal代替,但有这一切背后的逻辑还是在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM