ECMAScript6标准的特性已于2015年全部完成,并被正式命名为ECMA2015

临时死区( Temporal Dead Zone )

JavaScript引擎在 预编译代码发现变量声明时,要么将它们提升至作用域顶部(遇到var声明),要么将声明放TDZ中(遇到let和const声明)。访问TDZ中的变量会触发运行时错误,只有执行过变量声明语句后,变量才会从TDZ中移出,然后方可正常访问

  1. if (condition) {
  2. console.log(typeof value)
  3. let value = 'blue'
  4. }
  5. console.log(typeof value)
  6. if (condition) {
  7. let value = 'blue'
  8. }

Map集合

Map key和value 支持所有的数据类型,key的等价判断是通过Object.is()实现的
所以数字5和字符串”5”会被判定为两种类型,这一点与对象不太一样,因为对象的属性名会被强转成字符串

在对象中,无法使用对象作为对象属性的键名;但是在Map中,可以这样做

let obj = Object.create(null)
let key1 = {}
let key2 = {}
obj[key1] = 5
console.log(obj[key2])

let map = new Map()
map.set(key1, 10)
map.set(key2, 100)
map.get(key1)
map.get(key2)

Weak Map 集合中的key必须是一个对象,如果使用非对象会报错
集合中保存的是这些对象的弱引用,如果在弱引用之外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时也会移除Weak Map集合中的键值对。

迭代器(Iterator)和生成器(Generator)

迭代器

function createIterator(items) {
    var i = 0
  return {
      next: function() {
        var done = (i >= items.length)
      var value = !done ? items[i++] : undefined
      return {
          done: done,
        value: value
      }
    }
  }
}
var iterator = createIterator([1, 2, 3])
console.log(iterator.next())

生成器是一种返回迭代器的函数, 没当执行完一条yield语句后函数就会自动停止

yield只可在生成器内部使用,在其他地方使用会导致程序抛出语法错误

function *createIterator() {
    yield 1
  yield 2
  yield 3
}
let iterator = createIterator()
console.log(iterator)

可迭代对象和for-of循环

可迭代对象具有Symbol(Symbol.iterator)属性
在ECMAScript6中,所有的集合对象(Array, Set, Map)和字符串都是可迭代对象

// for-of循环每执行一次都会调用可迭代对象的next()方法,并将迭代器返回的结果对象value属性存到一个变量中
// 循环将持续执行 直到返回对象的done属性的值为true
let values = [1, 2, 3]
for (let num of values) {
    console.log(num)
}

如果将for-of用于不可迭代对象,则会报错 Uncaught TypeError: obj is not iterable
默认迭代器

let values = [1, 2, 3]
let iterator = values[Symbol.iterator]()
console.log(iterator.next())

// 检测对象是否为可迭代对象
function isIterable(obj) {
    return typeof obj[Symbol.iterator] === 'function'
}