我有一个问题,想知道如果你从一个对象调用setTimeout
,然后delete
d对象,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
也存储了对其的引用回调?
本质上,我的问题是:
container.timer
真的被删除了吗?- 为什么
setTimeout
回调container.timer.end
仍然运行? 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);
因此 setTimeout
在 this.end
中保存对函数的引用,并在几秒钟后调用它。
只有当 nothing 不再持有对它的引用时(除了可能的循环引用),某些东西才会被垃圾收集。如果某些东西存储在闭包或回调中,并且仍然可以引用回调,则不会对其进行 GC,至少在没有任何东西可以再引用它之前不会。
关于javascript - 为什么删除对象后setTimeout仍然调用回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60949633/