Node.js: `this` 运算符在模块作用域中使用时的上下文是什么?
Node.js: What is the context of the `this` operator when used in module scope?
代码
我写了下面的代码,保存为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
它 returns:
I am global
undefined
问题
为什么不return:
I am global
I am global
?
Node.js中的所有脚本文件都在自己的执行上下文中执行,而浏览器在全局执行上下文中执行所有脚本文件。
在没有特定上下文的情况下调用函数时,通常会默认为全局 object in Node.
print(); //global execution context -> 'I am global'
console.log (this.foo); // no context -> undefined
函数的this
属性在调用函数时设置,默认指向调用函数的对象,除非通过bind
等方法设置值, apply
或 call
。
值得注意的是,Node中的一个模块(相当于一个文件)被包裹在一个function()中,像这样:
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();
returns yellow
因为内部函数无法访问任何外部函数的 this
值,对于此类内部函数,这是 this
的标准行为默认为全局对象(浏览器中的 window 对象)。
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();
returns orange
和 undefined
因为它是 myObject
调用 print
。它returns undefined
相对于this.melon
,因为myObject
没有属性这个名字的瓜。
Console.log(this) 在模块范围内
console.log
命令是 Node 全局对象上的 属性 函数值,因此您会期望以下代码
global.apple = ‘yellow’;
global.console.apple = 'yellow';
console.log(this.apple);
到 return yellow
因为 console.log()
与 global.console.log()
相同。这意味着 console.log()
被全局对象调用,因此您会期望 this
指向 global.apple
或 global.console.apple
。然而,全局对象上的一些函数实际上是在模块范围内执行的(参见 Global objects),在这个范围内,Node 的设计者选择将 this
的值设置为对象 exports
],它作为参数传递给包装 Node 模块的函数。
上面的代码因此 returns undefined
因为 exports
没有名称为 apple 的 属性。
在 Node 模块中,this
按照设计引用模块的 exports
对象:
console.log(this === exports); // true
使 console.log(this.foo)
等同于 console.log(exports.foo)
.
换句话说,this
既不引用全局对象,局部变量也不会神奇地成为 exports
的属性。
因为 exports.foo
不存在,你得到 undefined
。
代码
我写了下面的代码,保存为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
它 returns:
I am global
undefined
问题
为什么不return:
I am global
I am global
?
Node.js中的所有脚本文件都在自己的执行上下文中执行,而浏览器在全局执行上下文中执行所有脚本文件。 在没有特定上下文的情况下调用函数时,通常会默认为全局 object in Node.
print(); //global execution context -> 'I am global'
console.log (this.foo); // no context -> undefined
函数的this
属性在调用函数时设置,默认指向调用函数的对象,除非通过bind
等方法设置值, apply
或 call
。
值得注意的是,Node中的一个模块(相当于一个文件)被包裹在一个function()中,像这样:
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();
returns yellow
因为内部函数无法访问任何外部函数的 this
值,对于此类内部函数,这是 this
的标准行为默认为全局对象(浏览器中的 window 对象)。
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();
returns orange
和 undefined
因为它是 myObject
调用 print
。它returns undefined
相对于this.melon
,因为myObject
没有属性这个名字的瓜。
Console.log(this) 在模块范围内
console.log
命令是 Node 全局对象上的 属性 函数值,因此您会期望以下代码
global.apple = ‘yellow’;
global.console.apple = 'yellow';
console.log(this.apple);
到 return yellow
因为 console.log()
与 global.console.log()
相同。这意味着 console.log()
被全局对象调用,因此您会期望 this
指向 global.apple
或 global.console.apple
。然而,全局对象上的一些函数实际上是在模块范围内执行的(参见 Global objects),在这个范围内,Node 的设计者选择将 this
的值设置为对象 exports
],它作为参数传递给包装 Node 模块的函数。
上面的代码因此 returns undefined
因为 exports
没有名称为 apple 的 属性。
在 Node 模块中,this
按照设计引用模块的 exports
对象:
console.log(this === exports); // true
使 console.log(this.foo)
等同于 console.log(exports.foo)
.
换句话说,this
既不引用全局对象,局部变量也不会神奇地成为 exports
的属性。
因为 exports.foo
不存在,你得到 undefined
。