Gök*_*dal 35 javascript node.js
我有一个加载的JavaScript文件require.
// 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"
);
Run Code Online (Sandbox Code Playgroud)
我的问题是:this在var中a = this;是一个空对象,而this函数中的语句是node.js全局对象的阴影.我知道this关键字在函数中有所不同,但我无法理解为什么第一个this不等于全局,this而函数等于全局.
如何node.js的注入global,以this在功能范围,以及它为什么不其注入到模块的范围?
aps*_*ers 57
以下是澄清情况必须了解的一些基本事实:
在Node模块的顶级代码中,this相当于module.exports.这是你看到的空对象.
当您使用this在函数中,值this之前重新确定每一个执行的功能,并且它的值由下式确定如何执行该功能.这意味着this如果调用机制不同(例如aFunction()vs. aFunction.call(newThis)vs. emitter.addEventListener("someEvent", aFunction);等),则完全相同的函数对象的两次调用可以具有不同的值.在您的情况下,aFunction()在非严格模式下运行具有this设置为全局对象的函数.
当JavaScript文件require作为节点模块时,Node引擎在包装函数内运行模块代码.使用thisset to 调用该模块包装函数module.exports.(回想一下,上面的函数可能会以一个abitrary this值运行.)
因此,您获得不同的this值,因为每个值都this位于不同的函数内:第一个在Node创建的模块包装函数内部,第二个在内部aFunction.
the*_*eye 31
要理解这一点,您需要了解Node.js实际上将您的模块代码包装到一个函数中,就像这样
(function (exports, require, module, __filename, __dirname) {
var test = function(){
console.log('From test: ' + this);
};
console.log(this);
test();
});
Run Code Online (Sandbox Code Playgroud)
详细解释可以在这个答案中找到.
现在,这个包装函数实际上是这样调用的
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);
Run Code Online (Sandbox Code Playgroud)
因此,this在模块级别,实际上是exports对象.
你可以这样确认
console.log(this, this === module.exports);
// {} true
Run Code Online (Sandbox Code Playgroud)
在Javascript中,值this是在调用函数时确定的。创建函数时不行。在模块最外部作用域的nodeJS中,其值this是当前module.exports对象。当函数被调用为对象的属性时,此值更改为被调用的对象。您可以简单地通过点对点规则记住这一点:
调用函数时,可以
this通过查看函数调用的位置来确定的值。点左边的对象是的值this。如果点中没有剩余的对象,则其值this是该module.exports对象(window在浏览器中)。
注意事项:
es2015没有自身绑定的箭头功能this。call,apply和bind可以弯曲有关this值的规则。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 }
Run Code Online (Sandbox Code Playgroud)
输出: