Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js:“this”操作符在模块作用域中使用时的上下文是什么?_Javascript_Node.js_Global Variables_This - Fatal编程技术网

Javascript Node.js:“this”操作符在模块作用域中使用时的上下文是什么?

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

代码

我编写以下代码并将其另存为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.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