JavaScript经典面试题

for(var i = 1; i <= 3;i++){
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    },0)
    console.log("这是下面的i:"+i)
}

输出: 在这里插入图片描述
OK!为啥输出结果是这样子的呢?

所用知识点:作用域,闭包,异步

相信大家对for循环已经很了解了,应该只是对setTimeout有点陌生

setTimeout(function(){
    console.log(2)
},0)
console.log(1)

输出 1,2

由此可见,我们使用setTimeout的时候是一种异步机制。setTimeout有两个参数,第一个是函数,第二个是执行的时间间隔值,默认毫秒。异步指的是当函数在执行这个事件时,把函数的参数放在事件对列中,等主程序执行完,然后再执行这个事件。体现在我们的例子中,就是当程序执行到setTimeout时,会将setTimeout中的参数放在主程序执行的事件队列里,当主程序执行完毕之后,才会执行setTimeout中的内容。
当setTimeout的时间为0代表等待主程序执行完之后再执行异步的程序,若不为o则代表执行主程序的同时开始计时,等时间到了之后再执行程序。


接下来分析一下代码运行流程:

i = 1
console.log("这是下面的i:"+i)           // 1
i++						 
console.log("这是下面的i:"+i)           // 2 
i++
console.log("这是下面的i:"+i)           // 3
i++
console.log("这是上面的i:"+i)			// 4
console.log("这是上面的i:"+i)			// 4
console.log("这是上面的i:"+i)			// 4

那么到这一步应该对这个理解了吧。
还有一个问题就是作用域。如果我们执行的程序是这样子的

for(let i = 1; i <= 3;i++){
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    },0)
    console.log("这是下面的i:"+i)
}

输出:
这是下面的i:1
这是下面的i:2
这是下面的i:3
这是上面的i:1
这是上面的i:2
这是上面的i:3

变量提升:使用var时候声明变量是函数作用域,作用在全局,在预解析时会将变量提升到函数顶部,在这里也就是全局的顶部,而let声明的变量是块级作用域,在预解析时候会把变量提升在for循环的第一行。
代码分析:

for(let i = 1; i <= 3;i++){
	let i = 圆括号中的值
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    },0)
    console.log("这是下面的i:"+i)
}

// 执行流程
// 每次输出i的值,i都会根据作用域链去找他的值。
// 第一次
	let i = 1
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    },0)
    console.log("这是下面的i:"+i)
    i++
// 第二次
    let i = 2
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    },0)
    console.log("这是下面的i:"+i)
    i++
// 第三次
	let i = 3
	setTimeout(function(){console.log("这是上面的i:"+i)},0)
	console.log("这是下面的i:"+i)
	i++
--------------------
然后在这里呢,我们会看到setTimeout中的i依次为1,2,3  只是在每次执行的时候都将setTimeout
中的值放在了主程序之后,所以我们会输出1,2,3,1,2,3这样的结果

关于let和var在for循环中的表现可以参考以下链接:

https://blog.csdn.net/wlk2064819994/article/details/79772388

当然如果我们想要让setTimeout中的值先输出也可以,将函数改为立即执行函数

for(var i = 1; i <= 3;i++){
    setTimeout(function(){
        console.log("这是上面的i:"+i)
    }(i),0)								// 立即执行函数
    console.log("这是下面的i:"+i)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章