在 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。
首先,有几点:
- 您不应编写这样的代码,它依赖于从环境中继承的
this
的某些隐式值。如果你的意思是访问全局对象,那么编写显式引用全局对象的代码。
- 如果您 运行 此代码位于
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
.
在浏览器中执行这段代码与在nodeJs中不同。
let abc = (() => {
function xyz() {
this.man = "XYZ"
}
xyz();
this.man = "ABC";
})()
console.log(man);
预期的答案是在节点中生成的 XYZ,但在浏览器中找到了 ABC。
首先,有几点:
- 您不应编写这样的代码,它依赖于从环境中继承的
this
的某些隐式值。如果你的意思是访问全局对象,那么编写显式引用全局对象的代码。 - 如果您 运行 此代码位于
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
.