ES6_关键字const和let

1、let关键字

ES6不再使用var来声明一个变量,而使用let,可以认为let是优化后的var。

基本用法

它的用法类似于var,但所声明的变量,只在声明变量所在的代码块内有效。

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

for循环的计数器,就很适合使用let声明。

for(let i = 0;i < 10;i++){
	//do something
}
console.log(i);	//ReferenceError:i is not defined

如果使用var声明for循环计数器。

for(var i = 0;i < 10;i++){
	//do something
}
console.log(i);	//10

产生区别的原因是:
var声明的变量为全局变量,全局只有一个变量i;
let声明的变量仅在块级作用域内有效,当前的i只在本轮循环有效,每一次循环的i其实都是一个新的变量。

你可能会问,如果每一次循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?
这是因为JavaScript引擎内部会记住上一轮循环的值,初始化本轮循环的变量i时,就是在上一轮循环的基础上进行计算的。

另外,for循环还有一个特别之处,设置循环变量的那一部分是一个父作用域,而循环体内部是一个单独的子作用域。

for(let i = 0;i < 3;i++){
	let i = 'a';
	console.log(i);
}
// a
// a
// a

上面代码允许输出3次a。这表明循环内部的i和循环计数的i不在同一个作用域,有各自单独的作用域。

不存在变量提升

“变量提升”现象,指变量可以在声明前使用。
使用var声明的变量便存在“变量提升”现象,值为undefined。
let声明的变量纠正了这种现象,它所声明的变量必须在声明后使用,否则就会报错。

//var关键字声明变量的情况
console.log(a);	//输出为undefined
var a = 1;

//let关键字声明变量的情况
console.log(b);	//ReferenceError:b is not defined
let b = 2;
暂时性死区

ES6明确规定,如果区块存在let和const声明变量,从一开始就形成了封闭作用域。凡在声明之前使用这些变量,就会报错。
也就是说,即使存在全局变量声明,在区块中再次声明同名变量,在区块中使用这个变量是会报错的,不再受外部的影响。这在语法上,称为“暂时性死区”(temporal dead zone,检查TDZ)。

var t = 1;
{
	t = 2;	//ReferenceError:t is not defined
	let t;
}

在没有let之前,typeof运算符是百分之百安全的,永远不会报错,现在这一点不成立了。

typeof x;	//ReferenceError:x is not defined
let x;

比较隐蔽的TDZ:

function b(x = y,y = 2){
	return [x,y];
}

b();	//ReferenceError:y is not defined

var m = m;	//不报错
let n = n;	//ReferenceError:n is not defined
不允许重复声明

同一作用域内,let关键字不允许重复声明同一个变量。

function f1(){
	let a = 10;
	var a = 1;
}
f1();	//SyntaxError: Identifier 'a' has already been declared

function f2(){
	let a = 10;
	let a = 1;
}
f2();	//SyntaxError: Identifier 'a' has already been declared

function f3(arg){
	let arg;
}
f3();	//SyntaxError: Identifier 'arg' has already been declared

function f4(arg){
	{
		let arg;
	}
}
f4();	//不会报错

2、const关键字

基本用法

const声明的是一个只读常量。一旦声明,常量的值就不能改变。这就意味着,const一旦声明变量,就必须立即初始化。

const PI = 3.14;
console.log(PI);	//3.14

PI = 3.14159;	//TypeError: Assignment to constant variable

const b;	//SyntaxError: Missing initializer in const declaration

const关键字也和let关键字一样:
只在声明所在的块级作用域内有效;
不存在变量提升;
存在暂时性死区。

本质

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
对于简单数据类型(数值、字符串、布尔值),等同于常量;
对于复合数据类型(主要对象和数组),const只保证指向实际数据的指针是固定的,至于它指向的数据结构是不是可以变,就完全不能控制。

const obj = {};

//为obj添加一个属性
obj.prop = 123;
console.log(obj.prop);	//123

//将obj指向另一个对象
obj = {};	//TypeError: Assignment to constant variable

如果真的要将对象冻结,应使用Object.freeze方法。

var constantize = (obj)=>{
	Object.freeze(obj);
	Object.keys(obj).forEach((key,i)=>{
		if(typeof obj[key] === 'object'){
			constantize(obj[key]);
		}
	})
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值