Javascript I';我对两种不同的输出感到困惑,因为setTimeout是异步的,fn定义应该更新为';2';在执行回调时
如果我将第二个函数表达式更改为函数声明,则两个超时都将记录“1”,这从pov中完全可以理解,但在这里,由于我们使用函数表达式,因此根据我的说法,在两个超时中执行回调时,第二个定义应覆盖第一个Javascript I';我对两种不同的输出感到困惑,因为setTimeout是异步的,fn定义应该更新为';2';在执行回调时,javascript,function,asynchronous,callback,Javascript,Function,Asynchronous,Callback,如果我将第二个函数表达式更改为函数声明,则两个超时都将记录“1”,这从pov中完全可以理解,但在这里,由于我们使用函数表达式,因此根据我的说法,在两个超时中执行回调时,第二个定义应覆盖第一个 var fn = function () { console.log('1'); }; setTimeout(fn, 1000); //output: 1 setTimeout(()=>{ fn();
var fn = function () {
console.log('1');
};
setTimeout(fn, 1000); //output: 1
setTimeout(()=>{
fn();
}, 1000); //output: 2
fn = function () {
console.log('2');
};
这令人困惑,因为它需要深入理解js如何处理javascript 您的代码有两个超时。当第一个函数运行时,JS事件循环(处理超时函数)中的函数fn设置为以1000ms运行 此时,函数fn记录
1
,因此在事件循环中,javascript引擎将计划在1000ms内运行函数console.log('1')
这一部分似乎显而易见。如果是这样,第二次设置超时有什么不同
好的,()=>{fn()}
特别意味着应该找到并执行函数fn
因此,
setTimeout(()=>{
fn();
}, 1000);
表示:1000毫秒后,应找到函数fn
,然后执行。因此,如果同时更改了fn
,则将执行更新版本
这与第一次设置超时不同,在第一次设置超时中,fn
的实际内容设置为在1000ms内执行,而不是在该点被命名为“fn”的任何函数
这就是为什么第二个timeout函数将运行更新版本的
fn
这令人困惑,因为它需要深入了解js如何处理javascript
您的代码有两个超时。当第一个函数运行时,JS事件循环(处理超时函数)中的函数fn设置为以1000ms运行
此时,函数fn记录1
,因此在事件循环中,javascript引擎将计划在1000ms内运行函数console.log('1')
这一部分似乎显而易见。如果是这样,第二次设置超时有什么不同
好的,()=>{fn()}
特别意味着应该找到并执行函数fn
因此,
setTimeout(()=>{
fn();
}, 1000);
表示:1000毫秒后,应找到函数fn
,然后执行。因此,如果同时更改了fn
,则将执行更新版本
这与第一次设置超时不同,在第一次设置超时中,fn
的实际内容设置为在1000ms内执行,而不是在该点被命名为“fn”的任何函数
这就是为什么第二个超时功能将运行更新版本的
fn
,因为OP特别提到:
提升是指在执行脚本之前将变量或函数声明移动到文件顶部。对于变量,只有定义向上移动,其值仍然未定义。而函数声明则挂在顶部
这里有函数表达式,它类似于变量,它们的值不会被提升。
因此,循序渐进:
在第1行中,fn获取值。
在第2行中,setTimeout获取一个要运行的函数,即fn。(以后也会执行)
在第3行中,setTimeout获取一个要运行的函数,它不是fn,而是一个调用fn的函数。
然后执行第4行,其中fn的值将改变
注意:如果两个函数表达式都是声明,那么两次都将打印2
function fn() {
console.log('2');
};
由于OP特别提到了吊装: 提升是指在执行脚本之前将变量或函数声明移动到文件顶部。对于变量,只有定义向上移动,其值仍然未定义。而函数声明则挂在顶部 这里有函数表达式,它类似于变量,它们的值不会被提升。 因此,循序渐进: 在第1行中,fn获取值。 在第2行中,setTimeout获取一个要运行的函数,即fn。(以后也会执行) 在第3行中,setTimeout获取一个要运行的函数,它不是fn,而是一个调用fn的函数。 然后执行第4行,其中fn的值将改变 注意:如果两个函数表达式都是声明,那么两次都将打印2
function fn() {
console.log('2');
};
在这种情况下,提升是不相关的,因为重新分配是在第二次超时运行
fn()
之前发生的。如果两者都是一个函数声明,那就很重要了(我稍后会解释)
我认为您确实了解代码中发生了什么,但只是想了解一下相同的内容:
fn
变量fn
函数传递直接引用的同时,触发setTimeout
setTimeout
并向其传递对新函数的引用,请注意,此新函数正在“关闭”该fn
变量,这意味着如果在执行函数之前更改此变量,它将拾取更改fn
变量(还记得上一步的注释吗?)1
fn
变量所做的更改,并执行“new”fn
函数,因此2
被记录到控制台