Node.js:在模块作用域中使用“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

在 Node 模块中,this设计是指模块的exports对象:

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

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

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

由于exports.foo不存在,因此您可以undefined.

Node.js 中的所有脚本文件都在自己的执行上下文中执行

,而浏览器在全局执行上下文中执行所有脚本文件。调用没有特定上下文的函数时,它通常会默认为 Node 中的全局对象。

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

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

值得注意的是,Node 中的一个模块(相当于一个文件(被包装在一个 function(( 中,如下所示:

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

这意味着下面的所有代码片段实际上都是在这个包装函数中执行的。有关更多详细信息,请参阅 vars 在 Nodejs 中的存储位置。

控制台.log(这个(在函数内

以下代码:

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 的标准行为是默认为全局对象(浏览器中的窗口对象(。

控制台.log(这个(在对象内部

以下代码:

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。它返回与this.melon相关的undefined,因为myObject没有名称为瓜的属性。

控制台.log(此(在模块范围内

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

global.apple = ‘yellow’;
global.console.apple = 'yellow';
console.log(this.apple);

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

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

最新更新