一、var let const的区别
var 没有块级作用域、有变量提升,能重复声明。
let 有块级作用域、没有变量提升,不可重复声明。
const 有块级作用域、赋值常量后不可修改、没有变量提升、不可重复声明
参考图:
图片描述:
var 声明的循环:就是运行五次的setimeout代码 会放到右边异步队列,但不执行,里边的(i)等到左边同步的执行完才会执行,因为左边同步的var会重复声明覆盖变量值,只有在最后一个执行完才会输出, 而let则会锁住变量,也就是有块级作用域也就是右边异步队列会直接输出0,1,2,3,4,5
二、for循环中的异步问题
**问题描述:**当我们使用for循环时,里面执行异步操作(比如延时器,接口请求等等),就会出现里面执行的永远是最后一次循环的结果,原因是因为for循环是同步的,当异步操作还没走完,for循环已经全部执行完成了,所以得到的永远是最后一次的结果。
解决方法如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<script type="text/javascript">
window.onload = function () {
// 问题描述:当我们使用for循环时,里面执行异步操作(比如延时器,接口请求等等),就会出现里面执行的永远是最后一次循环的结果,原因是因为for循环是同步的,当异步操作还没走完,for循环已经全部执行完成了,所以得到的永远是最后一次的结果。
var ps = document.getElementsByTagName("p");
// 方法一 使用闭包
for (var i = 0; i < ps.length; i++) {
(function (r) {
setTimeout(function () {
console.log(r)
})
})(i)
}
// 方法二:使用let 或 const块级作用域,每个for循环的变量只对本次循环有效
for (let i = 0; i < ps.length; i++) {
setTimeout(function () {
console.log(i)
})
}
}
</script>
</body>
</html>