let
1、块级作用域
2、不允许重复声明
3、不存在变量提升
4、不与顶层对象挂钩
一、块级作用域
var声明的变量会无视块级作用域,不管你if判断还是for循环
if(1){
var a=6;
}
console.log(a) //输出6
在大多数语言中,在块级作用域声明的变量都是活不出块级作用域的
int main () {
if(1){
int a=6;
}
cout<<a<<endl;//报错
}
这也是js经常被开发者诟病的原因之一,好在let的出现解决了这一问题,let和const声明的变量的只在块级作用域在中生效。
这个性质主要解决对于li的绑定的点击事件中,以下代码在页面中分别点击111、222、333,那么在控制台中将会打印三次3,因为var声明的变量不受块级作用域约束,所以当页面生成的适合,i已经为3了,所以不管点击哪一个li得到的结果都是3。
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
<script>
var oli = document.querySelectorAll("ul li")
for(var i = 0; i < oli.length ; i++){
oli[i].onclick = function(){
console.log(i)
}
}
</script>
而只需要将var修改为let问题就迎刃而解了。
二、不允许重复声明
使用var重复声明是不会报错的,但是let和const都不行
let a = 1;
let a = 2;// 报错
三、不存在变量提升
理解这个就得搞清楚暂存性死区。
在我的理解里,在全局作用域或者块级作用域里,某个变量声明之前的空间都是这个变量的暂存性死区。
如上图,从if代码块开始到变量a声明之前都属于变量a的暂存性死区,从for代码块开始到变量b声明之前都属于变量b的暂存性死区。
var和let以及const关于暂存性死区的区别就是,在暂存性死区使用变量,var会进行变量提升,let和const则不会进行变量提升,而是直接报错。
if(1){
console.log(a); //undefined
var a=1;
}
//上下代码等同,var声明的变量a被提升到代码块的顶部
if(1){
var a;
console.log(a);//undefined,变量提升
var a=1;
}
--------------------------------
if(1){
console.log(a); //报错
console.log(b); //报错
let a=1;
const b=2;
}
四、不与顶层对象挂钩
//在浏览器环境中:
var varVariable = 1;
let letVariable = 2;
console.log(window.varVariable); // 输出: 1
console.log(window.letVariable); // 输出: undefined
//在Node.js环境中:
var varVariable = 1;
let letVariable = 2;
console.log(global.varVariable); // 输出: 1
console.log(global.letVariable); // 输出: undefined
所以,let声明的变量不与顶层对象挂钩,只在声明它的作用域内有效。
const
1、常量
2、块级作用域
3、不允许重复声明
4、不存在变量提升
5、不与顶层对象挂钩
一、常量
由const声明的变量是常量,所以天然拥有常量的两大特性,第一声明的时候就要进行初始化,第二不允许修改。
const a; //报错,没有进行初始化
const b=1;
b=2; //报错,不允许修改
二、三、四、五和let一样
const的值一定不能修改吗?
值得一提的是在js的复杂类型中const的不允许修改指的是地址不允许修改,比如对象里的键值对的值是可以更改的。
const obj = {
name:"starry",
age:18
}
obj.age = 22;
console.log(obj.age)//22,可以修改
obj = {
name:"wang"//报错,不能修改
}
函数,数值同理。
当然如果你连对象属性也不想让其他人修改,可以使用freeze函数进行冻结。
const obj = Object.freeze({
name:"starry",
age:18
})
obj.age = 22;//不报错但是修改失败
console.log(obj.age)//18
关于es6let和const,我的总结到此为止,如有错误请指出。