三个不同的' this '行为用于三个不同的JS引擎



我正在学习this关键字,以及它在常规函数与ES6箭头函数和函数表达式方面的不同含义,当我试图在Chrome, Deno和Node中运行以下代码时,我遇到了一些奇怪的事情。所以我准备了如下内容:

:

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:webdevjs_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
<<p>节点/strong>输出:
PS E:webdevjs_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, …}

根据我对此的理解,对于箭头函数this没有显式绑定,并且指的是定义箭头函数的范围的this,而对于常规函数this指的是调用它的上下文,Chrome的输出似乎对我最有意义。我不明白为什么Node不能将全局对象识别为this。我最不介意Deno的输出,因为我想我可能不明白它到底想做什么。

有人能解释为什么Node, Deno和Chrome给我不同的输出吗?

三种不同JS引擎的this行为

那是一种误导人的说法。你有三个不同的JS环境,但它们都使用相同的引擎。

我被Node给我this = {}弄糊涂了。

这不是它给你的:this = [object global].

你在Node中没有看到的是var count显示为this.count。获得这种行为的一种方法(我不知道Node是不是这样做的)是将整个代码包装在IIFE中。

(function() {
/* YOUR CODE HERE... */
})();

在Chrome中,你会看到相同的行为,因为var count只是一个函数局部变量。

正如@Barmar所说,默认为严格模式(除了将代码包装在IIFE中),你会得到Deno的行为。

结论:在全局作用域中依赖this不是一个好主意。尝试将this仅用于将在对象上调用的方法(例如,如果您在任何地方都有foo.bar(),那么bar() {...}的主体可能使用this来引用foo)。

最新更新