let
类似于var,但其声明的变量只在let命令所在代码块中有效
let支持块作用域,var不支持
// let支持块作用域
// var不支持块作用域
{
var i = 2;
let j = 3;
}
console.log(i); // 2
console.log(j); // 报错:j is not defined
变量提升,把声明提升到作用域最前面也就是顶部
-
var可以变量提升。
if (true) { console.log(temp); // undefined let temp = "abc"; }
在var声明之前使用变量,变量为undefined。
-
let不能变量提升。
{ console.log(temp); let temp = "abc"; //报错:Cannot access 'temp' before initialization //未捕获引用错误:无法在初始化之前访问‘temp’ }
ES6明确规定,在块内使用 let 声明的变量之前,该变量都是不可用的。
在块顶部到let变量声明之间的区域被称为 “ 暂时性死区 ” 。
暂时性死区内不允许提前使用未声明的变量。
(var没有这种规定)
不允许重复声明
只要块内有let声明的变量,同一块内不允许再出现其他var/let声明的同名变量,会报错
{
let temp = "abc";
var temp = "xixi";
//报错:'temp' has already been declared
}
若同时存在两个var声明的同名变量,第二个会覆盖第一个
not defined != undefined
let i;
console.log(i); // undefined
console.log(j); // 报错:j is not defined
undefined是声明了但未赋值,而not defined是一种未声明的错误
扩展
// let支持块作用域
// 这里有三个作用域,也就是有3个同名不同作用域的t变量
for(let t = 0; t < 3; t++) {
let t = 2;
console.log(t); // 2 2 2
}
console.log(t); // 报错:t is not defined
// var不支持块作用域
// 这里有一个作用域,即全局作用域
// 所以这里相当于只有一个t1变量
for(var t1 = 0; t1 < 3; t1++) {
var t1 = 2;
console.log(t1); // 2
}
console.log(t1); // 3
for循环的“( )”为父作用域,花括号里是子作用域
const
类似于let,但其声明的是一个只读常量
常量
声明时必须立即初始化,一旦声明,其值不能被修改
// 声明时初始化,且值不允许被修改
const temp = "123";
temp = "abc";
console.log(temp); //报错:Assignment to constant variable.
}
支持块作用域
// 支持块作用域
const temp = "abc";
{
const temp = "123";
console.log(temp); // 123
}
console.log(temp); // abc
同一块级中不允许出现用let/var/const声明的同名变量
// 不允许同名变量存在
{
const temp = "123";
let temp = 123;
console.log(temp); // 报错:Identifier 'temp' has already been declared
}
支持块级作用域的变量不允许在同一作用域下出现同名变量
当常量保存的不是一个值,而是一个引用/地址的时候(比如对象),不能改变该引用/地址,但该变量引用的对象的属性值是可以改变的
// const声明常量初始化为一个对象时
// 该常量所引用的对象是可以更改成员的
// 但不能更改该常量的值
const foo = {y:100};
foo.x = 1000;
console.log(foo); // { y: 100, x: 1000 }
foo = {n:3000};
console.log(foo); // 报错: Assignment to constant variable.
}
扩展
-
浏览器的顶层对象为window
-
Node的顶层对象为global
var a = 100; console.log(window.a); //100
var定义的变量会关联到顶层对象中
let b = 100; console.log(window.b); //undefined const c = 100; console.log(window.c); //undefined
let/const定义的变量不会关联到顶层对象中