JS中var与let的特性研究

首先我看来看一下这么一个例子,点击div,div中的文字就会变成bye
<div class = "divs">Hello1</div>  
<div class = "divs">Hello2</div>  
<div class = "divs">Hello3</div>  
<script>
var byes = ["Bye1","Bye2","Bye3"];

for(var i = 0;i<3;i++){
    document.getElementsByClassName("divs")[i].addEventListener("click",function(){
        document.getElementsByClassName("divs")[i].innerHTML = byes[i];
    });
}

</script>

这个例子看似正常,但是点击时却会报错“test.html:19 Uncaught TypeError: Cannot set property 'innerHTML' of undefined"

在for循环里加一句输出i的值:

for(var i = 0;i<3;i++){
    document.getElementsByClassName("divs")[i].addEventListener("click",function(){
        console.log(i);
        document.getElementsByClassName("divs")[i].innerHTML = byes[i];
        
    });
}

i的值是3

把var换成let后,就正常了

for(let i = 0;i<3;i++){
    document.getElementsByClassName("divs")[i].addEventListener("click",function(){
        console.log(i);
        document.getElementsByClassName("divs")[i].innerHTML = byes[i];
        
    });
}

于是我们测试一下JS中var和let有什么特性:

for(var i = 0;i<5;i++){
    
}
console.log(i);//5
for(let i = 0;i<5;i++){
    
}
console.log(i);// i is not defined

第一个可以输出值,但是第二个却报错:i没有被定义

js里的let的这个特性与c++中的普通变量类似

#include <iostream>
using namespace std;

int main()
{
    for (int i = 0; i < 3; i++) {
    }
    cout << i;
    //报错 未定义标识符
}
int main()
{
    int i;
    for (i = 0; i < 3; i++) {

    }
    cout << i;
    //3

}

while的情况:

while(1){
    var a = 5;
    if(a==5){
        break;
    }
}
console.log(a);//5
while(1){
    let a = 5;
    if(a==5){
        break;
    }
}
console.log(a);//a is not defined

由上可见在局部定义的var,在全局还能使用,但是局部定义的let全局就不能用了。

但是在函数中情况又不一样了:

var a = 6;
while(1){
    var a = 5;
    if(a==5){
        break;
    }
}
console.log(a);//5

var b = 6;
function f1(){
    var b = 5;
    
}
f1();
console.log(b);//6

下面换成let:

let a = 6;
while(1){
    let a = 5;
    if(a==5){
        break;
    }
}
console.log(a);//6


let b = 6;
function f1(){
    let b = 5;
    
}
f1();
console.log(b);//6

总结:

JS中,var只有在函数中定义才是局部的,函数外部不能访问。循环体中定义,外部可以访问。

let更像C++中的普通变量的作用域特性,在哪定义的作用域就是哪里。

 

所以像开头那种遍历getElementsByClassName得到的数组,并添加回调函数的功能,可以使用let关键字定义循环变量

posted @ 2020-12-30 22:47  lucascube  阅读(181)  评论(0)    收藏  举报