Meaning of “this” in node.js modules and functions
我有一个由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // loaded by require() var a = this; //"this" is an empty object this.anObject = {name:"An object"}; var aFunction = function() { var innerThis = this; //"this" is node global object }; aFunction(); (function(anyParameter){ console.log(anyParameter.anObject); })( this //"this" is same having anObject. Not"global" ); |
我的问题是:var
node.js如何在函数作用域中将
以下是一些你必须了解的基本事实来澄清情况:
在节点模块的顶层代码中,
this 相当于module.exports 。那是你看到的空物体。在函数内部使用
this 时,this 的值在函数每次执行之前都会重新确定,其值由函数的执行方式决定。这意味着,如果调用机制不同(例如,aFunction() 与aFunction.call(newThis) 与emitter.addEventListener("someEvent", aFunction); 等),则完全相同的函数对象的两个调用可能具有不同的this 值。在这种情况下,aFunction() 在非严格模式下运行的函数this 设置为全局对象。当javascript文件作为节点模块被
require d时,节点引擎在包装器函数内部运行模块代码。调用该模块包装函数时,this 设置为module.exports 。(回想一下,上面的函数可以使用abitrarythis 值运行。)
因此,您得到不同的
要理解这一点,您需要理解node.js实际上是将模块代码包装到一个函数中,就像这样
1 2 3 4 5 6 7 | (function (exports, require, module, __filename, __dirname) { var test = function(){ console.log('From test: ' + this); }; console.log(this); test(); }); |
详细的解释可以在这个答案中找到。
现在,这个被包装的函数实际上是这样调用的
1 2 | var args = [self.exports, require, self, filename, dirname]; return compiledWrapper.apply(self.exports, args); |
因此,在模块级,
你可以这样确认
1 2 | console.log(this, this === module.exports); // {} true |
总结:
在javascript中,当调用函数时,会确定EDOCX1的值〔0〕。创建函数时不会。在模块最外层的nodejs中,
When a function is called you can determine the value of
this by looking at the place of the function invocation. The object left of the dot is the value ofthis . If there is no object left of the dot the value ofthis is themodule.exports object (window in browsers).
注意事项:
- 此规则不适用于没有自己绑定
this 的es2015 箭头函数。 - 函数
call 、apply 和bind 可以改变有关this 值的规则。
示例(nodejs):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | console.log(this); // {} , this === module.exports which is an empty object for now module.exports.foo = 5; console.log(this); // { foo:5 } let obj = { func1: function () { console.log(this); }, func2: () => { console.log(this); } } obj.func1(); // obj is left of the dot, so this is obj obj.func2(); // arrow function don't have their own this // binding, so this is module.exports, which is{ foo:5 } |
输出:
这是因为node.js模块中的默认全局对象是
- 小精灵
test.call({}) 或test.apply({}) :您正在指定作为this 使用的内容(第一个参数)var obj = {testRef: test}; obj.testRef() :this 设置在. 的左边,即obj 。
反驳你的回答
的确,模块顶层的
试图证明
1 2 | myGLobal = 5; this.myGlobal; // 5 |