gpt4 book ai didi

javascript - nodejs 和 Chrome 中 setTimeout 的不同行为

转载 作者:搜寻专家 更新时间:2023-10-31 23:14:57 26 4
gpt4 key购买 nike

代码示例是 -

global.a = 'aaa';

const obj = {
a: 'a',
desc() {
console.log(this);
console.log(this.a);
}
}

setTimeout(obj.desc, 2000)

当我在 nodejs 中运行此代码时,我得到以下输出:

Timeout {
_called: true,
_idleTimeout: 2000,
_idlePrev: null,
_idleNext: null,
_idleStart: 79,
_onTimeout: [Function: desc],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(asyncId)]: 6,
[Symbol(triggerAsyncId)]: 1 }
undefined

但是相同的代码,在 Chrome/Firefox 中将 global 更改为 window 打印 aaawindow对象,这是这个 MDN doc说,这是我所期望的。

我的印象是 nodejs 和 Chrome 都使用谷歌的 v8 JS 引擎来执行 JavaScript。那么为什么输出不同呢?还有更多的东西吗?我尝试搜索但找不到满意的答案。

Node 版本 - v9.10。
Chrome 的版本 - 版本 70.0.3538.110

最佳答案

node.js 有自己的计时器实现,这与浏览器实现不同(尽管它们通常可以以相同的方式使用)。这并没有真正记录下来,但是当您使用 setTimeout 时,它会创建一个 Timer 类的实例,并将回调作为参数传递。此回调分配给稍后使用的 Timer 实例的属性:

这意味着 node.js 中计时器的 this 上下文偶然被设置为 Timer 实例本身。浏览器显然做了一些不同的事情。

这主要是您原始代码中的语义问题:当您从对象传递函数属性时,它们会丢失上下文。您可以使用 .bind 来保留上下文,或者使用另一个函数直接在 obj 上调用 desc 来保留上下文。

setTimeout(obj.desc.bind(obj), 2000);
setTimeout(() => obj.desc(), 2000);

这两个将在 node.js 和浏览器环境中记录 objobj.a

关于javascript - nodejs 和 Chrome 中 setTimeout 的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53529250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com