什么是函数指针
const fn=()=>{ //fn:函数的内容, fn():函数执行后的结果
console.log("w");
return fn
}
在上面的函数中,fn就是代码块中箭头函数的函数指针,fn指代的就是函数体本身。
这里要区分 fn, fn() 的区别:fn——指函数体本身,fn()——函数执行结束后的结果。
毕竟fn(),加了括号就表示立即执行。
什么是定时器setInterval
具体内容可参见 setInterval MDN,这里只考虑第一、二个参数(函数和延迟时间),暂不考虑第三个参数。
let intervalID = setInterval(func, delay, [arg1, arg2, ...]);
上述代码的意思就是每经过delay毫秒,执行一次func。
两者混合使用时会怎么样
- fn中return,setInterval传入参数fn()
console.log("q");
const fn=()=>{
console.log("w");
return fn
}
setInterval(fn(),2000)
console.log("e");
上述代码的输出是:q, w, e, w, w, w, w...
2. fn中return,setInterval传入参数为一个函数,该函数函数体中调用fn
console.log("q");
const fn=()=>{
console.log("w");
return fn
}
setInterval(()=>{fn()},2000)
console.log("e");
上述代码的输出是:q, e, w, w, w, w, w...
3. fn中不return,setInterval传入参数fn()
console.log("q");
const fn=()=>{
console.log("w");
}
setInterval(fn(),2000)
console.log("e");
上述代码的输出是:q, w, e
4. fn中不return,setInterval传入参数fn
console.log("q");
const fn=()=>{
console.log("w");
}
setInterval(fn,2000)
console.log("e");
上述代码的输出是:q, e, w, w, w, w, w...
5. fn中return,setInterval传入参数fn
console.log("q");
const fn=()=>{
console.log("w");
return fn
}
setInterval(fn,2000)
console.log("e");
上述代码的输出是:q, e, w, w, w, w, w...
总结规律,得出结论
上述5个示例中:
- 1和3的输出结果中w在e前面,即只有setInterval中传入的第一个参数是fn()时,fn函数才会立即执行;
- 2、4、5的输出结果是一样的,这说明只有setInterval传入的第一个参数是函数体本身,定时器就会重复执行传入的函数,但又因为传入的是函数指针(即函数体)而非带括号的立即执行语句fn(),所以fn不会在console.log("e")之前立即执行;
- 3中没有重复输出,因为这个例子中传入的参数是fn()且fn函数没有return任何东西,对于fn()而言,它的本质只是把fn执行一遍,但它什么都不是(fn的函数类型是void,什么都没返回,相当于啥也不是),所以setInterval接收到第一个参数时感受应该就和下面的猫猫表情包一样,就很迷惑,这是个啥???我明明是要接收函数来着,这给我传了个啥???所以它不会去重复执行fn,因为我们也没把fn传给setInterval;
后面的console.log语句为什么会先于前面的setInterval执行
因为直接输出语句console.log属于微任务,而定时器setInterval属于宏任务,在js执行机制中,微任务总是先于宏任务执行。
关于微/宏任务的知识点,这个b站上的小视频->js宏任务与微任务<-讲的蛮生动的,有兴趣的小伙伴可以去瞅瞅~