先看现象:
setTimeout(console.log('12345'), 1000)
setTimeout(()=>{
console.log('67890')},1000)
例1:
for (var i = 0; i < 10; i++) {
setTimeout(console.log(i), 1000)
}
例2
for (var i = 0; i < 10; i++) {
setTimeout(()=>{
console.log(i)}, 1000)
}
例子1和例子2的区别
主要在于定时器的第一个参数,是一个函数还是一个函数的调用。
我们传入一个函数对的调用,他会立马执行,并不会管第二个参数多少毫秒。
当我们传入一个函数的时候(函数体),他会等毫秒数到了一定条件后执行函数。
我们打印一下console这个构造函数
所以:我们例1就是第一个参数传入了一个函数调用
for (var i = 0; i < 10; i++) {
setTimeout(console.log(i), 1000)
}
他会立即执行。
下面我们改写一下底层的console.log这个函数:
函数体的代码是在一秒钟之后执行的
传入函数体
let num =10
console.log = function(params=10){
num++
params+=num
console.dir(params)
}
for (var i = 0; i < 10; i++) {
setTimeout(()=>{
console.log(i)}, 1000)
}
或者
let num =10
console.log = function(params=10){
num++
params+=num
console.dir(params)
}
for (var i = 0; i < 10; i++) {
setTimeout( console.log, 1000)
}
传入函数调用:
函数体的代码是在立即执行的
let num =10
console.log = function(params=10){
num++
params+=num
console.dir(params)
}
for (var i = 0; i < 10; i++) {
setTimeout( console.log(), 1000)
}
主要区分setTimeout的第一个参数是函数还是函数调用
函数:等待定时时间到了执行函数;
函数调用:直接执行函数。
个人理解:
在浏览器读取代码提取到定时器的调用栈中,这个时候需要先将函数读取,加入到定时器调用栈,是函数的话,等待EQ,进而执行;是函数体的话读取就等于结束,读取的时候直接调用了这个函数,并没有走定时器调用栈,按照同步代码执行。
例子:
for (var i = 0; i < 10; i++) {
setTimeout( console.log("我是定时器里面输出的"+i), 1000)
console.log("我是正常的啊")
}
没有任何延迟的全部输出,同步。