javascript - 三种不同 JS 引擎的三种不同 `this` 行为

标签 javascript node.js v8 deno

我正在学习 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:\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

Node 输出:

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, …}

根据我对此的理解,对于箭头函数 this 没有显式绑定(bind),指的是定义箭头函数的作用域 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)。

关于javascript - 三种不同 JS 引擎的三种不同 `this` 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69296664/

相关文章:

javascript - Twitter-bootstrap 3 附加侧边栏菜单在向下滚动时未显示完整

javascript - 数组和可观察数组有什么区别?

node.js - 在 Windows 7 中打开太多文件(EMFILE 错误)

javascript - 跟踪 Web 应用程序中所有 Javascript 的执行

javascript - 从列表中删除

node.js - 有没有一种方法可以通过 Electron/node.js应用程序访问诸如CORTANA的Windows API?

node.js - 为什么有时 npm install 在 mac 上不起作用?

c++ - v8远程调试c++

c++ - NodeJS Nan C++ 将嵌套对象绑定(bind)到插件实例

javascript - 为什么网站图标不可见