三种不同的 JS 引擎的三种不同的 `this` 行为
Three different `this` behaviours for three different JS engines
我正在学习 this
关键字以及它在常规函数与 ES6 箭头函数和函数表达式方面的不同含义,我在尝试 运行 以下内容时遇到了一些奇怪的事情Chrome、Deno 和 Node.js 中的代码。所以我准备了以下内容:
示例:
function foo(n) {
console.log("***Begin Foo****")
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
console.log("****End Foo****")
this.count++;
}
var count = 1;
for (let i = 0; i < 5 ; ++i) {
foo(i)
}
console.log("From global this.count = "+this.count)
console.log(this)
Deno 输出:
PS E:\webdev\js_scratchspace> deno run .\another_this.js
***Begin Foo****
error: Uncaught TypeError: Cannot read property 'count' of undefined
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
^
at foo (file:///E:/webdev/js_scratchspace/another_this.js:24:64)
at file:///E:/webdev/js_scratchspace/another_this.js:31:5
节点输出:
PS E:\webdev\js_scratchspace> node .\another_this.js
***Begin Foo****
n = 0
this = [object global]
this.count = undefined
****End Foo****
***Begin Foo****
n = 1
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 2
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 3
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 4
this = [object global]
this.count = NaN
****End Foo****
From global this.count = undefined
{}
Chrome 输出:
***Begin Foo****
n = 0
this = [object Window]
this.count = 1
****End Foo****
***Begin Foo****
n = 1
this = [object Window]
this.count = 2
****End Foo****
***Begin Foo****
n = 2
this = [object Window]
this.count = 3
****End Foo****
***Begin Foo****
n = 3
this = [object Window]
this.count = 4
****End Foo****
***Begin Foo****
n = 4
this = [object Window]
this.count = 5
****End Foo****
From global this.count = 6
Window {window: Window, self: Window, document: document, name: '', location: Location, …}
根据我的理解,where for arrow functions this
没有显式绑定,指的是定义箭头函数的作用域 this
,而对于常规函数 this
指的是调用它的上下文,Chrome 的输出对我来说似乎最有意义。例如,我不明白为什么 Node 不会将全局对象识别为 this
。我最不关心 Deno 的输出,因为我想我可能不明白它到底想做什么。
有人可以解释为什么 Node、Deno 和 Chrome 给我不同的输出吗?
Three different this
behaviours for three different JS engines
这是一种误导性的表述方式。您拥有三个不同的 JS 环境,但它们都使用相同的引擎。
I am befuddled by Node giving me this = {}
.
这不是它给你的:this = [object global]
。
您在 Node 中看不到的是 var count
显示为 this.count
。实现该行为的一种方法(我不知道 Node 是否正在这样做)是将整个代码包装在 IIFE 中。如果你这样做:
(function() {
/* YOUR CODE HERE... */
})();
在 Chrome 中,您会看到相同的行为,因为那时 var count
只是一个函数局部变量。
正如@Barmar 所说,您可以通过 defaulting to strict mode 获得 Deno 的行为(除了将代码包装在 IIFE 中)。
结论:在全局范围内依赖 this
并不是一个好主意。尝试仅将 this
用于将在对象上调用的方法(例如,如果您在任何地方都有 foo.bar()
,那么 bar() {...}
的主体可能会使用 this
来引用 foo
).
我正在学习 this
关键字以及它在常规函数与 ES6 箭头函数和函数表达式方面的不同含义,我在尝试 运行 以下内容时遇到了一些奇怪的事情Chrome、Deno 和 Node.js 中的代码。所以我准备了以下内容:
示例:
function foo(n) {
console.log("***Begin Foo****")
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
console.log("****End Foo****")
this.count++;
}
var count = 1;
for (let i = 0; i < 5 ; ++i) {
foo(i)
}
console.log("From global this.count = "+this.count)
console.log(this)
Deno 输出:
PS E:\webdev\js_scratchspace> deno run .\another_this.js
***Begin Foo****
error: Uncaught TypeError: Cannot read property 'count' of undefined
console.log(`n = ${n}\nthis = ${this}\nthis.count = ${this.count}`)
^
at foo (file:///E:/webdev/js_scratchspace/another_this.js:24:64)
at file:///E:/webdev/js_scratchspace/another_this.js:31:5
节点输出:
PS E:\webdev\js_scratchspace> node .\another_this.js
***Begin Foo****
n = 0
this = [object global]
this.count = undefined
****End Foo****
***Begin Foo****
n = 1
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 2
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 3
this = [object global]
this.count = NaN
****End Foo****
***Begin Foo****
n = 4
this = [object global]
this.count = NaN
****End Foo****
From global this.count = undefined
{}
Chrome 输出:
***Begin Foo****
n = 0
this = [object Window]
this.count = 1
****End Foo****
***Begin Foo****
n = 1
this = [object Window]
this.count = 2
****End Foo****
***Begin Foo****
n = 2
this = [object Window]
this.count = 3
****End Foo****
***Begin Foo****
n = 3
this = [object Window]
this.count = 4
****End Foo****
***Begin Foo****
n = 4
this = [object Window]
this.count = 5
****End Foo****
From global this.count = 6
Window {window: Window, self: Window, document: document, name: '', location: Location, …}
根据我的理解,where for arrow functions this
没有显式绑定,指的是定义箭头函数的作用域 this
,而对于常规函数 this
指的是调用它的上下文,Chrome 的输出对我来说似乎最有意义。例如,我不明白为什么 Node 不会将全局对象识别为 this
。我最不关心 Deno 的输出,因为我想我可能不明白它到底想做什么。
有人可以解释为什么 Node、Deno 和 Chrome 给我不同的输出吗?
Three different
this
behaviours for three different JS engines
这是一种误导性的表述方式。您拥有三个不同的 JS 环境,但它们都使用相同的引擎。
I am befuddled by Node giving me
this = {}
.
这不是它给你的:this = [object global]
。
您在 Node 中看不到的是 var count
显示为 this.count
。实现该行为的一种方法(我不知道 Node 是否正在这样做)是将整个代码包装在 IIFE 中。如果你这样做:
(function() {
/* YOUR CODE HERE... */
})();
在 Chrome 中,您会看到相同的行为,因为那时 var count
只是一个函数局部变量。
正如@Barmar 所说,您可以通过 defaulting to strict mode 获得 Deno 的行为(除了将代码包装在 IIFE 中)。
结论:在全局范围内依赖 this
并不是一个好主意。尝试仅将 this
用于将在对象上调用的方法(例如,如果您在任何地方都有 foo.bar()
,那么 bar() {...}
的主体可能会使用 this
来引用 foo
).