ES6之let与const

一、letconst

  • 先说结论:letconst的用法类似var,都是用来声明变量, 这两者的区别在于:const声明一个只读的常量,一旦声明后就不能改变(实际上可以理解为const声明的那个变量的内存地址不能改变,也就是说,如果用 const 声明一个函数,函数内的值是可以改变的,只是不能重新指向另一个对象)。

  • 虽然用法类似,但比 var好用得多,理由如下:

1、不存在变量提升

console.log(a); //undefined
var a = 1;
console.log(b); //Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 2;

由于var存在变量提升,以上代码不会报错,经常会引发很多 bug;而let因为不存在变量提升,更方便检查错误。

2、存在暂时性死区(temporal dead zone)
ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。这就是暂时性死区。

ES6 规定暂时性死区和letconst语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。

3、不允许重复声明

//报错
function func(){
  let a = 1;
  let a = 2;
}
  • 在使用for 循环的时候,let还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。看栗子:
for (var i = 0;i<5;i++){
  setTimeout(function(){console.log(i)},500);
}
//控制台打印结果
5
5
5
5
5

for(let i = 0;i<5;i++){
  setTimeout(function(){console.log(i)},500)
}
//控制台打印结果
0
1
2
3
4

这是一道经典面试题,简单地说,之所以var声明的时候打印出 5 个 5,是因为 500ms 后打印出的 i 已经循环完毕,且循环体内部只有一个 i,此时 i = 5,所以打印出来5 遍 5;而用 let声明时,可以理解为循环体内部其实有 5 个 i,每个 i 代表一个值,所以打印出来的是 5 个 i 的值,分别是 0 到 4。

二、顶层对象的属性
顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。

顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。

ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

var a = 1;
window.a  // 1

let b = 2;
window.b // undefined

上面代码中,avar声明,所以是顶层对象的属性;blet 声明,不属于顶层对象的属性,所以返回undefined

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JavaScript共包含三个部分:ECMAScript、DOM和BOM,而我们今天开始所要讲的ES6的全称就是E...
    前端王睿阅读 886评论 5 17
  • let 和 const 命令 let 命令 块级作用域 const 命令 顶层对象的属性 gl...
    安小明阅读 998评论 0 0
  • let 命令 块级作用域 const 命令 顶层对象的属性 global 对象 let 命令 基本用法 ES6 新...
    嘉奇呦_nice阅读 1,648评论 0 2
  • 在ES6中新增加了let和const,现在来看看他们的基本用法。 let: 1:不存在变量提升 var命令会发...
    lionlsc阅读 176评论 0 0
  • let 一、块级作用域 块级作用域也称作词法作用域,存在于函数与块中{}let只在块级作用域中存在,因此当你在不同...
    lesdom阅读 576评论 0 0