深刻理解ES6之let与const

上个月本身花了 1300 买了阿(a)里(li)的 服 务 器来学习 node 及对应的框架,在 11 号以前它们有作活动,1300 的配置如今一年只要 86 元,三年只要229元,真心以为很划算了,能够点击本条内容进行参与javascript

1 为何ES6要引入let和const(var命令所存在的问题)

1.1 变量提高

if (false) {
  var a = 1
}
console.log(a)
复制代码

正常理解上,if语句断定为false,var a = 1不会执行,最后 console.log(a)应该会报错才对,但实际结果为undefined。 致使这个结果的缘由就是变量提高,上述代码能够理解为java

var a
if (false) {
  a = 1
}
console.log(a) // undefined
复制代码

这样结果就显而易见了。node

1.2 没有块级做用域

一个老生常谈的面试题、面试

var funcs = []
for (var i = 0; i < 3; i++) {
  funcs[i] = function () {
    console.log(i);
  };
}
funcs[0]() // 3
复制代码

由于没有块级做用域,因此 i 泄漏为全局变量,funcs数组中方法所引用的变量 i 都是这一全局变量,致使函数并无如预想的方式对变量i进行输出 0 1 2数组

1.3 能够重复声明

var a = 1
var a = 2
console.log(a) // 2
复制代码

变量能够被重复的声明,可能会致使程序产生意想不到的bug框架

1.4 在全局做用域中声明的变量会建立为全局变量做为全局对象的属性

var a = 1
console.log(window.a) // 1
复制代码

2 let和const与var的区别

引入let和const就是为了解决上述var所存在的问题,这也就二者之间的区别函数

  • 不会进行变量提高
  • 块级做用域
  • 不能够重复声明
  • 不会建立为全局对象的属性

可使用上面的例子进行检测学习

3 let和const之间的区别

3.1 let声明的变量能够从新赋值,const声明的则不能够,因此const在声明变量时就必定要进行初始化

let a = 1
a = 2 // 2
const b = 1
b = 2 // Uncaught TypeError: Assignment to constant variable.
复制代码

const声明不容许从新赋值,并非变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动,但容许修改值。这意味着当用const声明对象时,对象的修改就是不可控的了ui

const obj = {
  propName: 1
}
obj.propName = 2 // 2 这样是彻底能够的
复制代码

4 暂时性死区

letcosnt声明的变量,在声明以前,该变量都是不可用的,这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)spa

var a = 1
function foo () {
  console.log(a)
  let a = 2
}
foo() // Uncaught ReferenceError: a is not defined
复制代码

这段代码,按照let声明的变量不会进行变量提高理解时,foo方法中console.log(a)应该查找到全局的变量a,打印出2才对。为何会报错呢? 这就是由于暂时性死区 JavaScript 引擎在扫描代码发现变量声明时,要么将它们提高到做用域顶部(遇到 var 声明),要么将声明放在 TDZ 中(遇到 let 和 const 声明)。访问 TDZ 中的变量会触发运行时错误。只有执行过变量声明语句后,变量才会从 TDZ 中移出,而后方可访问。因此在声明foo方法时,函数内部的a已经被放到TDZ中,在未执行声明语句前使用都会报错。 上面的代码段也能够理解为只要块级做用域内存在let const命令,它所声明的变量就“绑定”(binding)这个区域,再也不受外部的影响

5 总结

let 和 const 的出现解决了 var 声明变量时存在的一系列问题,因此目前的最佳实践是:默认使用 const,只有当确实须要改变变量的值的时候才使用 let。这是由于大部分的变量的值在初始化后不该再改变,而预料以外的变量值的改变是不少 bug 的源头。

相关文章
相关标签/搜索