ES6:let和const

pmsa
1118
2021-05-28

let

let 声明的变量只在let所在的代码快内有效

块级作用域

在javascript中只有全局作用域和函数作用域,并不存在块级作用域

{
    var a = 0;
    let b = 1;
}
console.log(a);//0
console.log(b);//Uncaught ReferenceError: b is not defined

var声明的变量由于不存在块级作用域所以可以在全局环境中调用,而let声明的变量由于存在块级作用域所以不能在全局环境中调用。

不允许重复声明

var 可以声明多次,let 只能声明一次

{
  	var m = 1;
        var m = 2;
        let n = 3;
        let n = 4;
        console.log(m);
        console.log(n);
}

结果直接报错:Uncaught SyntaxError: Identifier 'n' has already been declared

不存在变量提升

使用let不会像使用var一样存在一个变量提升的现象。变量提升:即变量可以在声明之前使用,值为undefined

{
  	console.log(x);//undefined
        var x = 10;
        console.log(y);//报错 Uncaught ReferenceError: Cannot access 'y' before initialization
        let y = 20;
}

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

{
	var tmp = 123;

	if (true) {
  		tmp = 'abc'; // ReferenceError
  		let tmp;
	};
}

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错

const

const 声明一个只读的常量,一旦声明,常量的值就不能改变。意味着,一旦声明必须初始化,否则会报错。

{
	const a = 1;
        a = 3;
        console.log(a);
}

结果报错:Uncaught TypeError: Assignment to constant variable.

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

动物装饰