let
特性
- 没有预解析,必须先定义再使用;不存在变量提升 ,存在暂时性死区
//var声明变量的方式存在“变量提升”,即如下情况:
console.log(a);//输出undefined
var a = 2;
//let不允许这种情况,如果在变量未声明前使用则会报错,出现“暂时性死区”
console.log(b);//Uncaught ReferenceError: b is not defined
let b = 1;
//且还有个限制在区块中
var c = 4;
{ //报错
console.log(c);
let c = 2;
}
- 不允许重复声明
//报错
function fn(){
let a = 1;
let a = 3;//即便用var a = 3;也一样会报错
}
function fn(a){
let a; //报错
}
- 块级作用域(大括号{}为一个代码块)
{
let a = 1;
var b = 2;
}
console.log(a);//报错:a is not defined
console.log(b);//2
下面例子中变量i的作用域为全局(即全局中只有一个i),故每次调用i的值都会发生变化,循环中输出的也是全局的i。导致运行时输出的都是最终给i赋予的值3。
for(var i=0; i<3;i++){
setTimeout(function(){
console.log(i);///输出三个3
})
}
下面例子中变量i是let声明的,当前i就只在本轮的循环有效,即每次循环i都是一个新的变量,JavaScript引擎内部会记住上一轮的循环值,初始化本轮的i时再进行计算。
for(let i=0; i<3;i++){
setTimeout(function(){
console.log(i);///输出1,2,3
})
}
const
特性
- 针对基本类型:常量 若赋予固定的值 不能被修改
- 针对引用类型:const保证的是变量指向的那个内存地址不能改动。(地址不可变)而它指向的数据结构是否可变不能控制。
js数据存储机制:对于基础数据类型(Number、String、Boolean、Null、Undefined),其值保存在变量指向的内存地址中,按值访问,操作的也是实际值。对于引用类型或者说复合类型数据(Object、Array、Function等),其值保存在内存中的对象中,变量指向的内存地址中只是一个指针,按引用访问,操作的是对象的引用不是实际的对象。
const a='123';
a = 'set';//出错,不能被修改
const b ={
name:"why"
};
b.name = "hello";//可行
b = {};//报错
let const定义方法与var方法的区别
-
es5声明变量的方法:var、function
-
es6声明变量的方法有六种:var function let const import class
-
es5中没有var即自动创建了一个全局变量,相当于给全局对象新增一个属性
-
es6中将全局变量与全局对象的属性脱离开来。规定let、const、class声明的全局变量不属于全局对象的属性。
var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1
let b = 1;
window.b // undefined