问题描述
为什么此警报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()
如何执行?
这是如何做:
-
命中
setTimeout
Web API,该API具有应在0毫秒后执行的功能,但它将被发送到事件循环并在以后执行。 其余代码将被执行。 点击
return
声明。 它将访问inner
的值。 现在,请记住您的setTimeout函数尚未执行。 因此,该函数将移至原型链并找到inner
。inner
是在Global
上下文中定义的。 该值将被返回。最后,
outer()
将函数返回给f
,该函数由另一个setTimeout
执行。setTimeout
的函数也将发送到事件循环 。
现在, 事件循环有2个函数可以调用!
其中一个将重置“内部”的值,另一个将警告“初始”,但inner
的值将立即更改。
警报将在定义的1秒后显示。