javascript - 为什么删除对象后setTimeout仍然调用回调

标签 javascript settimeout jsobject

我有一个问题,想知道如果你从一个对象调用setTimeout,然后deleted对象,setTimeout回调是否仍然存在被调用?

显然是的。

var container = {
    timer: { // the object to be deleted
        start: function() {
            console.log('start');
            setTimeout(this.end, 2000);
        },
        end: function() {
            console.log('end');
        },
    },

    timerStart: function() { 
        this.timer.start();
        setTimeout(this.timerDelete, 1000);
    },

    timerDelete: function() {
        console.log(delete this.timer);
        console.log('deleted timer');
    },
};

调用 container.timerStart(); 后,我收到以下信息:

> container.timerStart();
  start
< undefined
  true
  deleted timer
  end

因此显示对象 container.timer 已成功删除,而且 container.timer.end 也在 container.timer 之后被调用> 已删除。我知道 delete 只删除引用,一旦对象的所有引用都被删除,它就会从内存中删除,但这是否意味着 setTimeout 也存储了对其的引用回调?

本质上,我的问题是:

  1. container.timer 真的被删除了吗?
  2. 为什么 setTimeout 回调 container.timer.end 仍然运行?
  3. setTimeout 实际如何引用此行为?

非常感谢任何反馈或阅读资源。谢谢!

最佳答案

does this mean that setTimeout also stores a reference to its callback?

是的,这正是正在发生的事情。它有点类似于:

const obj = {
  fn: () => console.log('fn')
};
const fn = obj.fn;
delete obj.fn;
fn();

Is container.timer actually deleted?

从某种意义上说,container 不再具有 timer 属性,是的,但是 timer 函数仍然存在,因为 setTimeout 仍然持有对它的引用。

Why does the setTimeout callback container.timer.end still run?

因为它也在 setTimeout 中排队。 start 立即运行,它执行

setTimeout(this.end, 2000);

因此 setTimeoutthis.end 中保存对函数的引用,并在几秒钟后调用它。

只有当 nothing 不再持有对它的引用时(除了可能的循环引用),某些东西才会被垃圾收集。如果某些东西存储在闭包或回调中,并且仍然可以引用回调,则不会对其进行 GC,至少在没有任何东西可以再引用它之前不会。

关于javascript - 为什么删除对象后setTimeout仍然调用回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60949633/

相关文章:

javascript - 在 Firebase Javascript 中保存数组或 map

javascript - 未捕获的类型错误 : Cannot read property 'Checked' of undefined - ReactJS

javascript - 浏览器是否跟踪事件计时器 ID?

java - 有没有办法知道用户是否拒绝了小程序?

javascript - 发送电子邮件函数: error because of formulas in blank rows

javascript - IP 地址存储为 int 会导致溢出吗?

Javascript - setTimeout 未定义?

html - 设置超时命令

java - 我应该使用哪个 JSObject?