var Liarry = document.getElementsByTagName('li');
/*
*方法一
*描述:自执行函数,将变量当参数传入(闭包的思想,保存当前的值)。
*/
for (var i = 0; i < Liarry.length; i++) {
(function (j){
Liarry[j].addEventListener('click', function () {
console.log(j);
})})(i);
}
/*
*方法二
*描述:将变量值保存在当前的li对象中。
*/
for (var i = 0; i< Liarry.length; i++){
Liarry[i].index = i
Liarry[i].addEventListener('click', function () {
console.log(this.index)
})
}
/*
*方法三
*描述:定义一个时间函数,将参数传入(本质是全局变量变为局部变量)
*/
for (var i = 0; i < Liarry.length; i++) {
clickEvent(i);
}
function clickEvent(j) {
Liarry[j].addEventListener('click', function () {
console.log(j);
})
}
/*
*方法四
*用let声明变量
*/
for (let i = 0; i < Liarry.length; i++){
Liarry[i].addEventListener('click', function () {
console.log(i);
});
}
*阐述(个人理解,有不足的地方欢迎评论区走一波):
1、var 声明的变量存在变量提升,var 声明的是全局变量。当js引擎执行到for循环时,会给每一个li添加一个click事件,此时并未触发该事件,click的回调并没执行,回调中的i并没赋值,直到i等于length终止循环,当触发click,回调执行,i去获取值,此时的值被length覆盖。
2、let 块级作用域,不存在变量提升(js规定它声明的变量是唯一的)。每次循环js引擎会把变量i重新声明初始化一次,变量i的每一次赋值只作用域本次循环,所以值不一样。