本篇简述 JS 函数的执行时机 和 setTimeout() 的使用情况。
JS 函数表达式有 具名函数、 匿名函数 、箭头函数和构造函数。
- 具名函数 是
function 函数名(形参1,形参2){
语句
return 返回值
}
- 匿名函数就是上面的 具名函数 去掉了函数名。
- 箭头函数:
let fn = (x,y) => {return x+y} - 构造函数
let fn = new Function('x','y','return x+y')(已经不常用了) 上述只是函数自身,不是函数调用。
let fn=()=>console.log('hi')
fn //函数自身
fn() //函数调用
关于函数的调用时机,时机不同,结果就不同。
例1:
let a=1
function fn(){
console.log(a)
}
fn() //打印出 1
a=2
上方代码打印的值为1,因为 fn() 是在 a = 2 之前调用的。
setTimeout()
setTimeout() 方法可以设置一个定时器。
例2:
let a=1
function fn(){
setTimeout(()=>{
console.log(a)
},0)
}
fn()
a=2 //打印出2
setTimeout() 是在定时器到期后执行一个函数或指定的一段代码。语法是
var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);
- function —— 是你想要在到期时间(delay毫秒)之后执行的函数。
- code —— 这是一个可选语法,你可以使用字符串而不是function ,在delay毫秒之后编译和执行字符串。(此方法不推荐)
- delay(可选)—— 延迟的毫秒数。delay取默认值0,意味着“马上”执行,或者尽快执行(但是实际延时比设定值更久,原因可看MDN,最小延迟时间>=4ms)
- arg1, ..., argN (可选)—— 附加参数,一旦定时器到期,它们会作为参数传递给function。
因此,例2 中的
setTimeout()将console.log(a)操作“尽快执行”了。虽然 fn() 是在 a=2 前调用的,但是由于“尽快执行”,使打印的 a 值是 a=2 后的结果。
同样如此的有 例3:
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
在for循环执行完毕后,i=6,之后“尽快执行”console.log(i),结果打印 6个6。
下面将 例3 更改,使其打印出0、1、2、3、4、5 。
方法1 :在 for 循环里使用 let 声明变量
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
方法2 : 把 for 循环放入定时器中
let i
setTimeout(function(){
for (i = 0; i<6; i++){console.log(i)}
},1000) // 1秒后打印 0 1 2 3 4 5