在函数的初始化和调用之间重新定义函数
Redefine function between its initialization and invocation
为什么警告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);
将超时设置为0并不一定意味着回调将立即运行。控制立即进行到下一行,在那里你返回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);
现在你会看到"Redefined",因为我们调用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);
但是你也会因为同样的原因在这里得到"Initial";当setTimeout
被调用时,inner
仍然指向原始版本
这是因为inner
的值是在所有其他JS执行之后设置的。该函数被发送到其他堆栈,并从main
堆栈中删除。即使将定时器设置为0 ms;setTimeout函数将在所有其他JS执行时执行。下面是程序的执行方式:
- 初始化
inner
和outer
。 - 执行
outer
,用返回值初始化f
。
但是outer()
是如何被执行的?方法如下:
- 命中
setTimeout
Web API,该API有一个函数应该在0毫秒后执行,但它将被发送到事件循环,并将在稍后执行。其余代码将被执行。 -
点击
return
语句。它将访问inner
的值。现在,请记住setTimeout函数还没有执行。因此,该函数将向上移动到原型链并找到inner
。inner
是在Global
上下文中定义的。 -
最后,
outer()
返回一个函数给f
,该函数由另一个setTimeout
执行。setTimeout
中的函数也会被发送到事件循环
现在,事件循环有两个函数要调用!其中一个将重置inner的值,另一个将警告"Initial",但是inner
的值将立即改变。
相关文章:
- 如何在JQuery函数中定义一个值,然后调用另一个函数并使用该值
- 现有函数未定义
- jQuery$.post可以在chrome、safari中工作,但不能在FF中工作(声明成功回调函数未定义)
- 粗体的ExecCommand函数的定义
- AngularJS ng repeat显示原型函数未定义
- 如何使Javascript函数“;定义的“;在使用jQuery时
- 具有不同函数调用定义的共享JavaScript文件
- 未捕获的引用错误:变量未在单击函数上定义
- jQuery onclick 函数:未定义不是一个函数
- 在构造函数中定义函数会比将其附加到原型消耗更多的内存
- 如何在单击超链接时调用同一函数中定义的函数
- 使用 Javascript 中的函数重新定义函数
- 函数未定义
- 为什么在jsfiddle中显示ReferenceError:函数未定义
- 函数未定义,实际定义时为
- 函数未定义的Javascript(Basic)
- 在Javascript构造函数中定义属性的正确方式
- JavaScript-如何将onload函数内部定义的变量取到外部
- 使用原型的自定义数组函数.新的 MyArray(1,2,3,4) 不工作
- 当前项未在新函数中定义(已延迟)