Javascript Node.js:“this”操作符在模块作用域中使用时的上下文是什么?
代码 我编写以下代码并将其另存为test.js:Javascript Node.js:“this”操作符在模块作用域中使用时的上下文是什么?,javascript,node.js,global-variables,this,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 a
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.js中的所有脚本文件都在其自己的执行上下文中执行,而浏览器则在全局执行上下文中执行所有脚本文件。 在没有特定上下文的情况下调用函数时,它通常默认为全局
函数的
此
属性在调用函数时设置,默认情况下指向调用函数的对象,除非该值是通过绑定
、应用
或调用
等方法设置的
值得注意的是,节点中的模块(相当于文件)被包装在函数()中,如下所示:
NativeModule.wrapper = [
‘(function (exports, require, module, __filename, __dirname) { ‘,
‘\n});’
];
这意味着下面的所有代码片段实际上都在这个包装函数中执行。有关更多详细信息,请参阅
控制台。在函数中记录(此)
以下代码:
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();
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();
返回黄色
,因为内部函数无法访问任何外部函数的this
值,对于此类内部函数,this
的标准行为是默认为全局对象(浏览器中的窗口对象)
Console.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();
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();
返回橙色
和未定义
,因为它是myObject
调用print
。它返回与this.melpool
相关的未定义的,因为myObject
没有名称为melpool的属性
Console.log(此)在模块范围内
console.log
命令是节点的全局对象的一个属性,具有函数的值,因此您需要以下代码
global.apple = ‘yellow’;
global.console.apple = 'yellow';
console.log(this.apple);
作为console.log()
返回yellow
与global.console.log()
相同。这意味着全局对象调用console.log()
,因此您希望This
指向global.apple
或global.console.apple
。但是,全局对象上的某些函数实际上是在模块范围内执行的(请参阅),在该范围内,节点的设计者选择将this
的值设置为对象exports
,该值作为参数传递给包装节点模块的函数
因此,上述代码返回未定义的,因为导出
没有名称为apple的属性。在节点模块内部,此
按设计指的是模块的导出
对象:
console.log(this === exports); // true
使console.log(this.foo)
等同于console.log(exports.foo)
换句话说,此
既不引用全局对象,也不神奇地成为导出的属性
由于exports.foo
不存在,您会得到未定义的节点模块不在全局范围内运行。谢谢@Bergi。那么,当在任何函数、对象等之外的文件中调用console.log时,您会如何表述它。您会说它是在“本地上下文”中调用的吗?它被称为“模块范围”。我想这是(虽然它本身被标记为重复。我不确定它是否是重复的-但谢谢你的链接。它链接到了关于Node.js是如何设计的非常有价值的信息。你的分析很奇怪。这个在控制台.log
中的值(即log
绑定到什么)苹果公司
@FelixKling:我想这并不奇怪。请看上面编辑的内容。如果你设置global.foo=function(){console.log(this.apple);global.apple='green'并调用foo(),它将返回'green'。那么为什么不应该设置global.console.log(this.apple);还返回“绿色”。因为节点的设计者选择让console.log在模块范围内运行,并在此范围内将其值设置为作为参数传递给包装器函数的导出对象。如果您还不知道,则不容易弄清楚。好吧,您非常关注console.log
,但问题与此无关o不要这样做。前两个例子只是演示了这个
在两种特定情况下是如何工作的:普通函数调用(globle对象)、对象方法(object)。这既不是特定于Node,也不是特定于控制台。log
。最后一个例子特别令人困惑,表明您还没有完全理解这种情况(无意冒犯)“您可能会期望以下代码[…]返回黄色
“我非常怀疑大多数开发人员所期望的。为了记录黄色
,此
必须引用控制台
。…您真的期望模块内的此
引用控制台
?”这意味着全局对象调用console.log()“甚至不清楚这意味着什么。对象不调用函数。定义了console
的位置以及调用它的方式/位置完全不相关。传递给console.log
的值在传递给函数之前就被计算过了。也许这更容易理解:var foo=this.apple;console.log(foo);
“全局对象上的某些函数实际上是在模块范围内执行的”同样,它与您调用的函数无关。您可以用任何其他任意函数替换console.log
,您将得到相同的结果。重要的是您正在模块的顶层访问此
。事实上,您非常关注console.l