一、let
- 定义的变量只在代码块中有效
{ var a =20; } console.log(a);//20 { let a = 20; } console.log(a);//报ReferenceError { let a =30; { console.log(a);//30 } }
2.在for循环外是访问不到的
for(var i=0;i<3;i++){ } console.log(i);//3 for(let j=0;j<3;j++){ } console.info(j);//报ReferenceError
3.不存在变量提升
console.log(foo);// 输出undefined var foo = 2; console.log(bar);// 报错ReferenceError let bar = 2;
4.暂时性死区
解读:只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响
var tmp = 23; if(true){ tmp = 'abc';// ReferenceError let tmp; }
含义:只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
5.不能在函数内部重新声明参数
{ let a = 10; let a = 20; console.log(a);//报错 Duplicate declaration "a" }
6.示例
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 用var定义,表示全局只有一个变量i,数组a的所有成员里面的i,指向的都是同一个i,所以调用时输出的都是最后一轮的i的值,即10
es6之前的解决方式
var a = []; for (var i = 0; i < 10; i++) { (function(i){ a[i] = function () { console.log(i); }; }(i))//采用立即执行函数(闭包) } a[6]();//6
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); //6 用let声明,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以输出的是6
二、const
1.const声明一个只读的常量。一旦声明,常量的值就不能改变
{ const a = 10; a = 20; console.log(a);//"a" is read-only }
2.声明必须赋值
{ const a;//如果是let a;则会弹出undefined,不会报错 console.log(a);//报错 }
3.对象(引用类型),可以修改赋值
{ const obj = { user:"张三" } obj.user = '李四'; obj.pwd = '123455'; console.info(obj.user,obj);//李四 }