for 循环中 var 和 let的区别是什么?

let homeTravelItemImg = document.getElementsByClassName("item-img");

let homeTravelItemIcon = document.getElementsByClassName("item-icon");

for (var i = 0; i < homeTravelItemIcon.length; i++) {
    homeTravelItemIcon[i].onclick = function() {
        homeTravelItemImg[i].style.opacity = '1';
        homeTravelItemIcon[i].style.display = 'none';
    }
}

代码主要实现的是,当我点击一个icon时,icon消失,并且背景图片的不透明度改变;

这里面当我触发点击事件时,控制台报错:

Uncaught TypeError: Cannot read property 'style' of undefined

而我将for循环的var 改为 let时,就不会报错,请问这是为什么?

是因为块级作用域的问题吗?

阅读 3.3k
4 个回答

你可以打个断点就知道了,在onclick里面,执行进去的时候,i的值应该是homeTravelItemIcon.length了
找不到相关的DOM节点,所以报错的。

在里面直接用this吧

let homeTravelItemImg = document.getElementsByClassName("item-img");

let homeTravelItemIcon = document.getElementsByClassName("item-icon");

for (var i = 0; i < homeTravelItemIcon.length; i++) {
    homeTravelItemIcon[i].onclick = function() {
        this.style.opacity = '1';
        this.style.display = 'none';
    }
}

//主要是非方法内部用var定义的话,相当于全局的,任何地方都可以访问到,浏览器引擎解析的时候也就不会
在内部开辟一个局部变量,而直接引用外部变量的地址了。

//使用let的方式应该跟以下这种方式是一致的。

for (var i = 0; i < homeTravelItemIcon.length; i++) {
  
    (function(i){homeTravelItemIcon[i].onclick = function() {
        homeTravelItemImg[i].style.opacity = '1';
        homeTravelItemIcon[i].style.display = 'none';
    }})(i);
}

变量提升
作用域

1.var会导致变量提升,如果你在for循环中var了i,那么在该作用域中是可以找到i的
如for(var i =0;i<5;i++){}
console.log(i) //5

2.let是Es6中的声明方式,但是所声明的变量,只在let命令所在的代码块内有效。
for(let i =0;i<5;i++){}
console.log(i) //报错
详见:http://es6.ruanyifeng.com/#do...

推荐问题
宣传栏