方法一:通过闭包实现,弄个立即执行函数保存变量值
var i ; // 通过var声明时没有块级作用域
for(i = 0 ;i < 10; i++){
(function(i){
var a = document.createElement("a");
a.innerHTML = i + "<br>";
a.addEventListener('click',function(){
alert(i)
})
document.body.appendChild(a);
})(i)
}
方法二:通过let声明,let有块级作用域
// let 有块级作用域
for( let i = 0 ;i < 10; i++){
var a = document.createElement("a");
a.innerHTML = i + "<br>";
a.addEventListener('click',function(){
alert(i)
})
document.body.appendChild(a);
}
方法三:通过拼接字符串记录下标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
for(var i=0;i<10;i++){
var a = document.createElement('a');
a.innerHTML= i + '<br>'
a.setAttribute('onclick',`alert(${i})`)
document.body.appendChild(a);
}
</script>
</body>
</html>
其他类似情况常见例子,每隔1秒打印1、2、3、4、5,
第一种思路:方法1、2、3是利用都是闭包的原理只是下标变化而已
// 方法 1:
for(var i=0;i<5;i++){
(function (i){
setTimeout(function(){
console.log(i+1)
},(i+1)*1000)
})(i)
};
// 方法 2:
for(var i=1;i<=5;i++){
(function (i){
setTimeout(function(){
console.log(i)
},(i)*1000)
})(i)
};
// 方法 3:
for(var i=0;i<5;i++){
(function (i){
setTimeout(function(){
console.log(i)
},(++i)*1000)
})(i)
};
第二种思路:setTimeout参数传递改变了
for(var i=0;i<5;i++){
setTimeout(`console.log(${i+1})`,(i+1)*1000)
}
使用该语法是不推荐的
, 原因和使用 eval()一样,有安全风险,参见 MDN | 永远不要使用eval
第三种思路:利用let在for循环中声明有块级作用域来实现的
for(let i=0;i<5;i++){
setTimeout(function(){
console.log(i+1);
},(i+1)*1000)
}
setTimeout更详细可以参考:在for循环中运行setTimeout的三种情况