JS 函数的执行时机

252 阅读2分钟

JS函数的不同执行时机,会影响到函数运行的输出结果,不能通过代码本身百分百判断函数输出什么,而是要根据函数具体的执行时机

案列一:为什么如下代码会打印 6 个 6

let i = 0
for(i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

打印出来是多少呢?

先分析一下执行过程 很明显,let i=0是声明在函数外面的全局变量,不影响里面的for循环

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式 用大白话来解释就是:for循环执行之后,马上打印出i。

for循环先执行一次,i=6之后再打印出6个i,得到的结果是6个6.

如下图

看到这里,有些同学肯定会有新的疑惑?

为什么是6个i呢? 不是0,1,2,3,4,5。因为setTimeout是一个异步任务,执行到这里的操作会被浏览器放到另一个队列里去,浏览器这个时候会继续往下执行,把下面代码执行完了才会执行setTimeout函数里的操作,这时候因为for循环已经把i加到6了,所以输出的全部都是6.

案列二:打印 0、1、2、3、4、5 的方法

for(let i=0;i<6;i++){
 setTimeout(()=>{
    console.log(i)
  },0)
}

是不是跟案列一很相似,结果是什么呢?

结果如下:

为什么呢? 是因为js在forlet一起用的时候会加东西,每次循环会多创建一个i,相当于复制了6个i,所以结果就是0,1,2,3,4,5。

除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5?

案列三:使用闭包的方法 使用函数闭包,我们定义一个匿名函数,并且把当前的i当做value传进入输出,即可打印出正确结果

for(i = 0; i<6; i++){
	(function(value) {
		  setTimeout(()=>{
		    console.log(value)
		  },0)
	}(i))
}

案列四:利用const关键字

for(i = 0; i<6; i++){
	const x = i
	setTimeout(()=>{
	   console.log(x)
	 })
}