ES6重修系列(1)

变量

var与变量提升

使用var关键字声明的变量,无论其声明位置在哪里,都会被视为声明于所在函数的顶部。如果声明不在函数内,则被视为在全局作用域的顶部。这就是变量提升

function getValue1(condition){
  if(condition){
    var value = 'v';
    return value;
  }else {
  	console.log(value)
    return null;
  }
}
getValue1(false)
// output:undefined

可以看出在varelse中可以调用,说明已经创建了 value

console.log(value);
var value = 10;
// undefined

块级声明

块级声明:让所声明的变量在指定块的作用域外无法被访问。

块级作用域在以下情况被创建

  1. 在一个函数内部
  2. 在一个代码块内部({}包裹)

let声明

再看一个例子,如果使用的是 let的话

function getValue2(condition){
  if(condition){
    let value = 'v';
    return value;
  }else {
  	console.log(value)
    return null;
  }
}
getValue2(false);

上述代码会直接报错。ReferenceError: value is not defined

禁止重复声明

在同一个块级声明中 let 声明的变量是唯一的。

var value = 'a';
let value = 'b';
// 报错
var value = 'a';
if (condition) {
	let value = 'b'
}
// 不会报错,括号内的value,会在其块级作用域内屏蔽对外部value的访问

const常量声明

使用const声明的变量是不可修改的,而且在声明时就需要完成初始化。

const value = 10;
// value声明、初始化后就不可修改

const demo;
demo = 10;
// error

对比const和let

let相似,const也是禁止重复声明的,且其作用域在块级声明内部。

const声明对象

const声明会阻止对于变量绑定与变量自身值的修改,但是对于变量成员的修改是可以的。

其实也很容易理解,对象是个引用,const person绑定的引用不可变化,但是其指针指向的值可以变化。

const person = {
	age: 10
}

person.age = 20;
// 可以执行

person = {
  age: 20
}
// error

暂时性死区

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,处于暂时性死区内(TDZ),只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

看一个例子:

var tmp = 123;

if (true) {
  typeof tmp;
  let tmp;
}

在进入块级作用域后,tmp就已经存在了,并且屏蔽了对于外部var tmp的访问,此时 tmp在暂时性死区中,处于不可访问的状态,所以typeof tmp报错。

再看一个例子:

if (true) {
  typeof tmp;// 依旧会报错
  let tmp;
}

如果在块级作用域内没有声明:

if (true) {
  typeof tmp;
}
// 可以正常运行不报错

循环中的块级绑定

首先,循环内部定义的 var在循环外部可以访问,let不能访问。

循环内的函数

let

var test = []
for (let i = 0; i < 10; i++) {
  test.push(function(){console.log(i)})
}
test[3]()
// output: 3

var

var test = []
for (var i = 0; i < 10; i++) {
  test.push(function(){console.log(i)})
}
test[3]()
// output: 10

const

var funcs = [];
	// 在一次迭代后抛出错误
	for (const i = 0; i < 10; i++) {
		funcs.push(function() {
		console.log(i);
	});
}
var funcs = [],
  object = {
    a: true,
    b: true,
    c: true
	};
// 不会导致错误
for (const key in object) {
  funcs.push(function() {
  	console.log(key);
	});
}
funcs.forEach(function(func) {
	func();
	// 依次输出 "a"、 "b"、 "c"
});

​ 当使用for-infor-of的时候,实际上const没有发生值的改变,所以不会报错。

块级绑定的最佳实践

ES6的发展过程中,广泛认可的变量声明方法是:

  1. 默认使用const
  2. 对于需要变动的变量使用let
原文地址:https://www.cnblogs.com/njuclc/p/12696599.html