在 nodeJS 中执行相同的代码会给出来自浏览器的不同输出,有人可以解释一下吗

execution of same code in nodeJS gives different output from browser, can one explain

在浏览器中执行这段代码与在nodeJs中不同。

let abc = (() => {
  function xyz() {
    this.man = "XYZ"
  }
  xyz();
  this.man = "ABC";
})()
console.log(man);

预期的答案是在节点中生成的 XYZ,但在浏览器中找到了 ABC。

首先,有几点:

  1. 您不应编写这样的代码,它依赖于从环境中继承的 this 的某些隐式值。如果你的意思是访问全局对象,那么编写显式引用全局对象的代码。
  2. 如果您 运行 此代码位于 strict mode 中,旨在防止常见的编程错误和问题,则此代码不会 运行。它会抛出异常。这进一步提示您不应该编写这样的代码。

此代码取决于 this 的两个默认值。

首先,它取决于this的顶级值。在浏览器中,它将是 window 对象。在 nodejs 模块中,这将是当前模块的 module.exports 对象。

其次,这取决于 this 的值将在您的函数调用 xyz() 中。在浏览器的草率模式下,这将是 window。在 nodejs 的草率模式下,这将是全局对象。因此,this.man = "XYZ" 在全局对象上设置了 属性。在严格模式下,xyz() 函数中 this 的值将是 undefined.

第三,你对 this.man = "ABC" 的赋值取决于 this 在你的顶级箭头函数定义点的词法值。在浏览器中,这也将是 window。在 nodejs 中,这将是 module.exports.

因此,在浏览器中,您的 xyz() 函数将 window.man 设置为 "XYZ",然后将 window.man 设置为 "ABC"

在 nodejs 中,您的 xyz() 函数将 global.man 设置为 "XYZ",然后您的箭头函数将 module.exports.man 设置为 "ABC"


最后,运行 在严格模式下插入:

"use strict";

作为文件中的第一行代码,你会得到一个错误:

TypeError: Cannot set properties of undefined (setting 'man')

因为 xyz() 函数内部的 this 将是 undefined(应该是)并且尝试在 undefined 上设置 属性 是类型错误。您在对象上设置属性。

在严格模式下 运行 所有代码是个好主意。该语言中越来越多的功能在严格模式下自动 运行,例如 class 方法,因为在严格模式下 运行 您的代码更好。它不会阻止您做任何没有更好方法的事情。它只是阻止你做你不应该做的事情(通常是意外的)。


为了更好地说明 nodejs,运行 这个:

let abc = (() => {
    function xyz() {
        this.man = "XYZ";    // sets global.man
    }
    xyz();
    this.man = "ABC";        // sets module.exports.man
})()
console.log(this == module.exports);
console.log(module.exports.man);
console.log(global.man)

你会得到这个输出:

true
ABC
XYZ

这里还有一点是,当你调用一个函数如xyz()时,xyz()执行中this的值是由函数的调用方式决定的。您可以看到对调用函数 here 的各种方式的解释,以及它如何影响函数内部 this 的值。

在草率模式下将其作为普通函数 xyz() 调用会将函数内部 this 的值设置为全局对象。在严格模式下将其作为普通函数调用会将函数内部 this 的值设置为 undefined.