Node.js:在模块范围内使用时,`this`运算符的上下文是什么?

时间:2016-02-16 12:13:01

标签: javascript node.js global-variables this

代码

我编写以下代码并将其保存为test.js:

var foo = 'I am local';
global.foo = 'I am global';

function print () {
     console.log(this.foo);
};

print(); 
console.log (this.foo); 

然后我使用命令node test.js在终端中运行它并返回:

I am global
undefined

问题

为什么不返回:

I am global
I am global

3 个答案:

答案 0 :(得分:3)

在Node模块中,this按设计引用模块的exports对象:

console.log(this === exports); // true

使console.log(this.foo)等同于console.log(exports.foo)

换句话说,this既不引用全局对象,也不局部变量神奇地成为exports的属性。

由于exports.foo不存在,您获得undefined

答案 1 :(得分:1)

Node.js中的所有脚本文件都在自己的执行上下文中执行,而浏览器则在全局执行上下文中执行所有脚本文件。 在没有特定上下文的情况下调用函数时,通常会默认为全局object in Node

print(); //global execution context -> 'I am global'
console.log (this.foo); // no context -> undefined

答案 2 :(得分:1)

函数的this属性在调用函数时设置,默认情况下指向调用函数的对象,除非该值由bindapply等方法设置或call

值得注意的是,Node中的模块(相当于一个文件)包含在一个函数()中,如下所示:

NativeModule.wrapper = [
  ‘(function (exports, require, module, __filename, __dirname) { ‘,
  ‘\n});’
];

这意味着下面的所有代码片段实际上都是在这个包装函数中执行的。有关详细信息,请参阅Where are vars stored in Nodejs

功能中的Console.log(this)

以下代码:

var apple = ‘red’;          // private variable in the wrapper function 
global.apple = ‘yellow’;    // property on the global object 

var foo = function () {

    var apple = ‘green’;
    console.log (this.apple);
}

foo();

返回yellow因为内部函数无法访问任何外部函数的this值,并且在这种内部函数的情况下,它是this默认为全局对象的标准行为(浏览器中的窗口对象)。

对象内的Console.log(this)

以下代码:

var apple = ‘red’;          // private variable in the wrapper function
global.apple = ‘yellow’;    // property on the global object 

var myObject = {

    orange: ‘orange’,
    print: function () {

    console.log (this.orange);
    console.log (this.melon);   
}}

myObject.print();

返回orangeundefined,因为myObject正在调用print。它返回与undefined相关的this.melon,因为myObject没有名称为melon的属性。

模块范围内的Console.log(this)

console.log命令是Node的全局对象上的一个属性,具有函数的值,因此您可以期待以下代码

global.apple = ‘yellow’;
global.console.apple = 'yellow';

console.log(this.apple);

返回yellow,因为console.log()global.console.log()相同。这意味着全局对象会调用console.log(),因此您希望this指向global.appleglobal.console.apple。但是,全局对象上的一些函数实际上是在模块范围内执行的(参见Global objects),在此范围内,Node的设计者已选择将this的值设置为对象exports },作为参数传递给包装Node模块的函数。

上面的代码因此返回undefined,因为exports没有名为apple的属性。