深入理解ES6之let与const

为什么ES6不鼓励用var声明变量了

在函数作用域或全局作用域中通过关键字var声明的变量,无论实际上是在哪里声明的,都会被当成是在当前作用域顶部声明的变量。

  • 举个栗子:
function getValue(condition){
	if(condition){
		var value = "blue";
		return value;
	}
	else{
		return null;
	}
}

这段代码按正常的眼光来看待,只有当condition的值为true的时候,变量value才会被创建,但是实际上,无论condition的值是什么,变量value都会被创建。在预编译阶段,JavaScript引擎会将上面的代码修改成这样。

function getValue(condition){
	var value;
	if(condition){
		value = "blue";
		return value;
	}
	else{
		return null;
	}
}

正如我在开头所说的那样,变量value 的声明被提升到了函数的顶部,但是赋值操作却依然在原处执行,这也就意味着,在else字句里,value变量也是能被访问到的,但是因为没有赋值,所以得到的结果是undefined。
这个机制被称为 变量提升(Hoisting)机制

块级声明

块级声明用于声明在指定块的作用域之外无法访问的变量。块级作用域存在于:

  • 函数内部
  • 块中1

简单来说就是用块级声明所声明的变量只能在该代码块中发挥作用。

let声明

let声明是块级声明,let声明在用法上和var是一样的,用let代替var来声明变量可以把变量的作用域限制在当前代码块中。let声明是不存在变量提升机制的,因此用let声明变量时一般把声明语句放在代码块的顶部,以便整个代码块都可以访问到该变量。
举个栗子:

function getValue(condition){
	if(condition){
		let value = "blue";
		return value;
	}
	else{
		//变量value在这里是不存在的
		return null;
	}
	//变量value在这里是不存在的
}

let的禁止重声明:如果作用域中已经存在某个标识符,此时再使用let来试图声明它就会报错。
举个栗子:

var a = 1;
let a = 2;

此时let不会给a赋值为2,而是会抛出错误,因为在一个作用域中不能用let重复定义已经存在的标识符。

var a = 1;
if(condition){
	let a = 2;
}

这样声明变量是不会报错的,因为它们不在同一个作用域中,所以不存在重声明的问题。

const声明

const声明是块级声明,使用const声明得到的不是变量而是常量,其值被初始化之后就不可以更改,这也意味着使用const声明常量必须进行初始化操作,如果用const声明常量时没有赋值将会抛出语法错误。
举个栗子:

const my_name = "炒米粉";
//语法错误,常量未初始化。
const my_age;
//语法错误,常量的值不能被改变
my_name = "炒河粉";

值得一提的是,const也是禁止重声明的,这点与let一致,这里就不赘述了。

用const声明对象:用const来声明对象的话是不允许修改绑定关系的,但是允许修改对象的属性值。
举个栗子:

const boy = {
	name:"炒米粉"
};
//修改对象属性的值是没有问题的
boy.name = "帅气的炒米粉";
//抛出语法错误
boy = {
	name:"帅气的炒米粉"
};

临时死区(Temporal Dead Zone)

JavaScript引擎在扫描代码发现声明的时候,要么将声明提升到作用域顶部(var的变量提升机制),要么将声明放入TDZ中(遇到let或const)。
访问TDZ中的变量将会抛出错误,当执行过变量声明语句后,该变量才会从TDZ中移出
举个栗子:

//num的TDZ起点
console.log("DO SOMETHING");
console.log(typeof num);
//num的TDZ终点
let num = 1;

上面的代码是会报错的,因为第二行代码仍处于num的TDZ中,却访问了num。
上面的栗子用的是let,如果换成const结果也是一样的。
相比上面的代码,这一段反而不会报错:

console.log(typeof num);//"undefined"
if(condition){
	let num = 1;
}

因为第一行代码是试图访问当前作用域中并不存在的变量,所以得到的是undefined,而不会报错。


  1. 块的定义:在字符 {} 之间的区域 ↩︎

原创文章 4 获赞 4 访问量 230

猜你喜欢

转载自blog.csdn.net/weixin_39342847/article/details/105822367