let
es6 新增的let 声明变量 但let只能在所声明的代码块内生效
{
//es6 新增的let 声明变量 但let只能在所声明的代码块内生效
let a = 1
var b = 2
}
console.log(b) //2
console.log(a) //ReferenceError: a is not defined.
let 不存在变量提升 在未定义之前使用 报错 但var在未定义之前使用 会输出undefined 建议: 先声明后使用
console.log(a) //undefined
var a = 1
console.log(b) //ReferenceError: b is not defined
let b = 2
暂时性死区:使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
let a = 1 //全局变量a
if(true){
a = 2
let a ; //局部变量a
console.log(a) //ReferenceError: a is not defined
}
//上面代码中,存在全局变量a,但是块级作用域内let又声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
//有些“死区”比较隐蔽,不太容易发现
function bar(x=y,y=2){
return[x,y]; //y is not defined
}
bar()
//上面代码中,调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于“死区”。如果y的默认值是x,就不会报错,因为此时x已经声明了。
function bar(x=2,y=x){
return[x,y];
}
console.log(bar()) //[2,2]
}
let不允许在相同作用域内,重复声明同一个变量。
function func(arg) {
let arg;
}
func() // 报错
function func(arg) {
{
let arg;
}
}
func() // 不报错
const
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
- const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
- const的作用域与let命令相同:只在声明所在的块级作用域内有效。
- const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const foo = {}; // 为 foo 添加一个属性,可以成功 foo.prop = 123; console.log(foo)// prop: 123 // 将 foo 指向另一个对象,就会报错 foo = {}; // TypeError: "foo" is read-only