【问题标题】:Why running same code is different between node env and chrome console?为什么在 node env 和 chrome 控制台之间运行相同的代码是不同的?
【发布时间】:2017-11-02 17:03:48
【问题描述】:
var name = "Global";

function funcA() {
    var name = "FunA";
    return function() {
        console.log(this.name);
    }
}

funcA()();

我使用节点在终端上运行上面的代码并返回undefined 但在 chrome 控制台中,它将返回 Global

为什么会这样?

【问题讨论】:

  • 对不起,只要编辑代码,它就会打印 Global 然后 undefined,为什么?
  • 我在 Node(承认古代 0.12.4)和 Chrome 中都看到了日志消息 Global,后跟返回值 undefined。你能展示一下Node做什么的截图吗?在 no 环境中,funcA()() 是否有返回值(默认 undefined 除外,因为缺少 returned 值)。 function() { console.log(this.name); } 里面有零个 return 语句。
  • 另外,请注意the danger of using a global variable called name,它将在浏览器代码中被字符串化。 (这里没有问题,因为它是一个字符串,但可能会导致其他类型的麻烦。)
  • 您是否将此代码作为模块运行? (模块中的顶级变量不是全局变量,这可以解释为什么您会看到记录的值不同。)
  • @apsillers 我相信他是通过 node test.js... 运行它的

标签: javascript node.js google-chrome scope


【解决方案1】:

1. 在浏览器环境中运行此脚本会强制顶级 var 成为全局 window 对象的属性。然后根据MDN

由于下面的代码不是严格模式,而且 this 的值不是由调用设置的,所以 this 将默认为全局对象,即浏览器中的 window。

因此,在该函数中调用 console.log(this.name); 意味着 this 将是指向全局 window 对象的链接,该对象将具有 name 属性。而window.name 的值为“Global”。

2. NodeJS 没有window 对象,但它有global 对象。在 NodeJS 环境中运行脚本会在两种情况下中断: (a) 作为模块运行(例如通过node test.js)和 (b) 不作为模块运行(例如直接在节点控制台中)。 第二种情况 (b) 与浏览器的工作方式相同:global 将接收name 属性,this 将是指向global 的链接, 所以this.name 的值将等于global.name 并且是“全局”。

但第一种情况 (a) 不同,根据NodeJS doc

Object 全局命名空间对象。

在浏览器中,顶级作用域是全局作用域。这意味着在浏览器 var 中某些东西将定义一个新的全局变量。 在 Node.js 中这是不同的。顶级范围不是全局范围; var 某个 Node.js 模块中的某些内容将是该模块的本地内容。

这样顶级 var 就变成了 Node 环境中的一个局部变量,并且由于 global 没有 name 属性, 调用console.log(this.name) 显示undefined

【讨论】:

  • 但是节点没有全局对象吗?
  • 所以,我的理解是这个答案隐含地表明 OP 的代码在模块内部运行,因此顶级 var name = "Global"; 不会创建全局变量,对吗?的确,如果属实,那将解释它,尽管我认为您应该更明确地说明该假设。
  • @apsillers 如果您定义global.name = "Global"; 而不是var name = "Global",它将起作用。
  • @Dreams:确实如此。每个 JavaScript 环境都有一个全局对象。但是,默认情况下存在哪些全局变量并没有标准化。
  • @apsillers 通过var 声明的变量不会成为 Node 中的 global 对象属性,就像浏览器中的 window 一样。
【解决方案2】:

var 在顶级作用域中定义了Global object 中的变量。

在浏览器或交互式节点会话的情况下,匿名函数调用中的this 指向Global object,但在脚本作为节点模块运行的情况下指向exports-object

直到严格模式……

【讨论】:

    猜你喜欢
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多