Javascript NodeJS中全局变量之谜

Javascript NodeJS中全局变量之谜,javascript,node.js,Javascript,Node.js,注意:这只是出于好奇,对我来说不是一个拦路虎 当我在做我的节点项目时,我碰到了一件让我困惑的事情,我不知道为什么会这样。请查找示例代码以理解问题 function a() { console.log(this === GLOBAL); //true } console.log(this === GLOBAL); // false a(); 现在,它清楚地说 顶级作用域不是全局作用域 因此,我从上面的注释中理解了为什么此在函数a(顶级)之外是假。但是在函数a中这个指向

注意:这只是出于好奇,对我来说不是一个拦路虎

当我在做我的节点项目时,我碰到了一件让我困惑的事情,我不知道为什么会这样。请查找示例代码以理解问题

function a() {
    console.log(this === GLOBAL);  //true
}    
console.log(this === GLOBAL);      // false
a();
现在,它清楚地说

顶级作用域不是全局作用域

因此,我从上面的注释中理解了为什么
函数a
(顶级)之外是
。但是在
函数a中
这个
指向
GLOABAL
,为什么

我使用的是
node-5.5.0
,但是我检查了
node-0.12
上的行为,它是一致的

也许是我这边的一些愚蠢的误会,请容忍我


更新:顺便说一下-
顶层中的这个
模块。导出
,函数中的这个是
全局的
,在JavaScript中,
这个
的值可能会引起很多混乱。我将尝试解释与此相关的部分:

  • 在“独立”函数中,
    成为全局对象
  • 在方法(即附加到对象的函数)中,此将成为其方法被调用的对象
例如

您对设置为“全局”的
的观察不是节点独有的,在浏览器中也是如此。JavaScript中有一种称为“严格模式”的东西,当启用时,它会使
this=undefined
的值在我们讨论的情况下变得更合理


如果您想了解更多关于这方面的信息,本文将提供大量信息。

您的问题与节点本身无关,而是与ECMAScript规范本身有关。你可能想了解和

在函数调用中仅为
全局
,因为您处于非严格模式;如果要使用
“严格使用”pragma,
未定义

提供了一些见解:

首先,在严格模式下传递给函数的值不会被强制成为对象(也称为“boxed”)。对于普通函数,这始终是一个对象:如果使用值为该值的对象调用所提供的对象;如果使用布尔值、字符串或数字调用,则为已装箱的值;或全局对象(如果使用未定义或null调用)。(使用call、apply或bind来指定特定的this。)自动装箱不仅会带来性能成本,而且在浏览器中公开全局对象也会带来安全隐患,因为全局对象提供对“安全”JavaScript环境必须限制的功能的访问。因此,对于严格模式函数,指定的this不会装箱到对象中,如果未指定,则未定义

因此,在非严格模式下,
函数中的此
将默认为
全局


在引擎盖下,节点模块封装在一个函数调用中,这将允许您访问
导出
要求
模块
\uuu文件名
\uu目录名
变量:

(function (exports, require, module, __filename, __dirname) {
  // your actual code will be injected here
});

此函数使用
导出
作为上下文运行(即
)。

您混淆了两个不同的概念。
this
的值与作用域无关。@昆汀:我试图为“任何函数之外的JS代码”(如浏览器中的全局作用域)找到一个名称,在这个问题中,我只是指不同作用域中的上下文。编辑问题看一看“顶级范围不是全局范围”没有多大意义,因为根据定义,全局范围是顶级范围。它们的意思可能是“执行模块代码的范围不是全局范围”,与浏览器中脚本的范围形成对比。@Bergi:这来自nodejs文档:OP似乎在不在函数中的情况下询问
这个
。@Ben:我的问题主要是关于
这个
是nodejs中的
模块。导出
(不适用于浏览器),在
严格模式
非严格模式
下。无论如何,提供的链接和一些其他读取会将其清除。Thanks@Bergi我认为这是问题的症结所在“但在函数a中,这是指向GLOABAL的,为什么是这样”:
(function (exports, require, module, __filename, __dirname) {
  // your actual code will be injected here
});