问题描述
为什么此警报Initial而不是Redefined :
var inner = function() { alert('Initial'); }
var outer = function() {
setTimeout(function() {
inner = function() { alert('Redefined'); }
}, 0);
return inner;
}
var f = outer();
setTimeout(f, 1000);
1楼
Vivin Paliath
2
已采纳
2015-07-30 19:22:44
将超时设置为零并不一定意味着回调将立即运行。
控制权立即前进到下一行,您在此处返回inner 。
目前尚未对其进行重新定义,并且f指向旧的inner ,这就是为什么您看到“ Initial”的原因。
将您的代码更改为以下内容:
var inner = function() { console.log('Initial'); }
var outer = function() {
setTimeout(function() {
inner = function() { console.log('Redefined'); }
}, 0);
return inner;
}
outer();
setTimeout(function() {
inner();
}, 1000);
现在您将看到“重新定义”,因为我们称outer ,它将在将来的某个时刻重新定义inner 。
然后,当我们在超时处理程序中调用inner()时,它指向重新定义的版本,因此它将显示“ Redefined”。
您可能想知道为什么我们不能仅仅这样做:
var inner = function() { console.log('Initial'); }
var outer = function() {
setTimeout(function() {
inner = function() { console.log('Redefined'); }
}, 0);
return inner;
}
outer();
setTimeout(inner, 1000);
但是出于同样的原因,您也会在这里得到“初始”字样。
当setTimeout被称为inner仍然指向原始版本。
2楼
Rex Overflow
0
2015-07-30 19:20:51
这是因为在执行所有其他JS之后设置了inner的值。
该函数将发送到其他堆栈,并从main堆栈中删除。
即使您将计时器设置为0毫秒 ;
setTimeout函数将在执行所有其他JS时执行。
这是程序的执行方式:
-
初始化
inner和outer。 -
执行
outer,并初始化f与返回值。
但是, outer()如何执行?
这是如何做:
-
命中
setTimeoutWeb API,该API具有应在0毫秒后执行的功能,但它将被发送到事件循环并在以后执行。 其余代码将被执行。 点击
return声明。 它将访问inner的值。 现在,请记住您的setTimeout函数尚未执行。 因此,该函数将移至原型链并找到inner。inner是在Global上下文中定义的。 该值将被返回。最后,
outer()将函数返回给f,该函数由另一个setTimeout执行。setTimeout的函数也将发送到事件循环 。
现在, 事件循环有2个函数可以调用!
其中一个将重置“内部”的值,另一个将警告“初始”,但inner的值将立即更改。
警报将在定义的1秒后显示。