关于nodejs中的this

javascript中的this是一个比较重要的知识点,有经验的jser都可以得心应手地运用this。但是在nodejs中,有时this的指向可能并不如我们所想。

this.js
1
2
3
4
5
console.log("this in global context:", this);

(function (){
console.log("this in function:", this);
})();

用nodejs运行上面的代码
可以看到第一个this是一个空对象,第二个this输出的是全局对象。

按正常的理解,在全局上下文中,this应该指向全局对象。在浏览器中为window,nodejs中是global。而这里最外层的this却是个空对象。

但是输入node进入REPL(交互式解释器),输入this,可以看到此时this又是全局对象了。

此时大概可以感觉到应该是和nodejs的模块机制有关。

在nodejs中,每个文件被视为一个模块,在执行每个文件中的代码时,nodejs会用一个如下的包装器函数将其包装:

1
2
3
(function(exports, require, module, __filename, __dirname) {
// 模块的代码实际上在这里
});

所以在REPL中也没有exports变量。

这个包装函数最终时这样调用的:

1
2
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);

所以在一个nodejs脚本的最外层,this的值实际上指向exports(不是module.exports)。

可以验证一下:

this.js
1
2
3
4
5
6
7
8
9
"use strict";

exports.name = "julien";

console.log("this in global context:", this, this === exports);

(function (){
console.log("this in function:", this);
})();
1
2
this in global context: { name: 'julien' } true
this in function: undefined

Reference