let
1.使用let所声明的对象只在命令所在的代码块内有效
//所谓代码块 简单的说就是在花括号里面
{
let a = 1;
var v = 2;
}
console.log(a);// a is not defined
console.log(b);//2
//注意:花括号里的let声明的变量不能被外面获取但是var可以
//类似于es5中我们常说的闭包
!function(){
var b = 1;
}();
console.log(b);
我们在代码块之外呢 是拿不到代码块内所声明的变量的
2.使用let声明的变量在预解析中是不能被解析的
es5中 声明之前是可以访问到变量a的,因为在浏览器的预解析过程中,寻找var 定义的变量和 function ,然后将这些变量保存在作用域中,值都是undefined;然后再往下逐步执行代码…(这里不做过多解释,想了解的自行google)
console.log(a);//undefined
var a = 1;
console.log(b);//报错 b 没有被定义
let b = 2;
暂时性死区
let b = 1;
function fn(){
b = 2; //暂时性死区
let b = 3;
}
3.不允许重复声明
在同一个作用域下不允许再次声明已经声明过的变量。
var a = 1;
let a = 2;
let b =1;
let b =2;
4.for循环中
还记得当年for循环中的坑么,也同时是大多数面试中的考点。
//假设我页面上有5个按钮 btn
for(var i=0,len=btn.length;i<len;i++){
btn[i].onclick = function(){
console.log(i);
}
}
//你就会惊讶的发现不管点击哪个按钮都会打印出5;
//当然 解决办法也很简单 要么就是给btn添加一个自定义属性
for(var i=0,len=btn.length;i<len;i++){
btn[i].index = i;
btn[i].onclick = function(){
console.log(this.index);
}
}
//要么就是闭包的方式
//将每次for循环的i传入到闭包函数中
for(var i=0,len=btn.length;i<len;i++){
(function(i){
btn[i].onclick = function(){
console.log(i);
}
})(i);
}
//但是呢,我们有了let之后就不用那么麻烦了,只需要简单的把var改成let就可以了
还有个需要注意的地方
for(let i=0;i<5;i++){ //有两作用域,循环语句中是父作用域,循环体中是子作用域 let i =10; console.log(i); } console.log(i);//报错了
const
const 和 let 很相似 同样在命令所在的代码块内有效,常量不会被提升,同时不能被重复声明。
不同的是:
1.声明时必须赋值.
2.1.使用const 声明常量是基本数据类型的时候,值不能被改变
2.2.如果声明的是引用数据类型(对象),则引用不能被改变,但是对象里的数据可以改变
const a = 1;
a = 2 ;//报错;
const obj = {};
obj.a = 1;//是可以的