var a = 1; var a = 2;//不会报错 let b = 1; let b = 2;//报错
2.let会产生块级作用域,且只在自己的作用域内生效,var不受限制
什么是块级作用域?当我们在{}中使用了let或者const时,{}的范围就是一个块级作用域,此时let只能在{}中使用,外部无法访问。像这样:
{ let a = 1; var b = 2; } console.log(a);//报错 console.log(a);//2
或者这样:
if(true){ let a = 1; var b = 1; } console.log(a); console.log(b);
//for循环用var var a = []; for (var i = 0; i < 5; i++) { a[i] = function () { console.log(i); }; } a[1]();//5 a[2]();//5 a[3]();//5 //for循环用let var b = []; for (let i = 0; i < 5; i++) { b[i] = function () { console.log(i); }; } b[1]();//1 b[2]();//2 b[3]();//3
在明白上面2个循环的区别之前,我们先来理一理知识点,我们要知道,for循环中设置循环变量的部位其实是一个父作用域,循环体内部是个子作用域。
在父子作用域中同时使用let的情况下,两个作用域就是互不干扰的两个块级作用域:
{ let a = 1; { console.log(a);//报错 let a = 2; console.log(a);//2 } console.log(a);//1 }
子作用域不使用let,还是可以正常继承父作用域,父也能读取子。
{ let a = 1; { var b = 2; console.log(a);//1 } console.log(a);//1 console.log(b);//2 }
所以下面这个循环输出了三次echo,因为在子作用域中申明的i跟父作用域中的i可以说是完全不同的两个i;
for(let i = 0;i<3;i++){ let i = ‘echo‘; console.log(i); };//输出三次echo
但如果你将let改为var,你会发现只输出一次,因为没有了块级作用域,父子作用域共用了一个变量i,第一次循环后,子作用域的i被改为了echo,父作用域中i<3的判断无法通过,所以只输出了一次。
那么回头再看看最初的两个循环,为什么var申明输出了3个5,而let输出了1,2,3呢,尝试去理解,说到底还是块级作用域搞的鬼。
console.log(a);//undefined var a = 1; console.log(b);//报错 let b = 1;
{ let a = 1; { console.log(a);//报错 let a =2; } }
三、const申明的特点
可以理解为,let的特性const都有,不能反复申明,存在块级作用域,不存在变量提升,也有暂时性死域的特点。
与let区别在于,const申明的是一个常量,一旦申明就无法修改,let可以,var就更不用说了。
就这样去记忆吧。
原文:https://www.cnblogs.com/echolun/p/10575676.html