# ES6食用指南

# let 、const 、 var 的区别

# var

  • var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined
  • 内层变量可能覆盖外层变量
  • 用来计数的循环变量泄露为全局变量

# let

  • 声明的全局变量不会挂在顶层对象下面
  • 所声明的变量一定要在声明后使用,否则报错,报错 ReferenceError
  • 暂时性死区,只要块级作用域内存在 let 命令,它所声明的变量就“绑定”( binding )这个区域,不再受外部的影响,在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。
  • 不允许重复声明

# const

  • 声明的全局变量不会挂在顶层对象下面
  • const 声明之后必须马上赋值,否则会报错
  • const 简单类型一旦声明就不能再更改,复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。
  • const 一旦声明变量,就必须立即初始化,不能留到以后赋值。
  • const 命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

# Symbol

Symbol在开发中用的比较少,但是对于原编程来说非常的强大,Symbol的用法很简单,我们可以通过Symbol()生成一个独一无二的元素,这里我们补充一下其他的知识点

Symbol(xxx)可以传入参数xxx,称为描述符,但是如果我们传入相同的描述符得到的2个结果也是不相等的




 
let s1 = Symbol('chenying')
let s2 = Symbol('chenying')
console.log(s1 === s2) // false

这里还需要注意一点,我们在传入描述符的时候尽量传入字符串,不要传入对象啥的,因为它内部会调用toString()方法,如




let s1 = Symbol({})
console.log(s1) //Symbol([object Object])

此外我们特别需要注意的一点,如果用Symbol作为一个对象的属性,那这个属性是不可枚举的




 




let s1 = Symbol()
let obj = {
    [s1]: 1
}
for (let key in obj) {
    console.log(obj[key]) //没有输出
}

最后我们在提一下Symbol.for(),它表示如果有这个symbol, 就不会重复申明了, 会用之前申明的那一个




 
let s1 = Symbol.for('chenying')
let s2 = Symbol.for('chenying')
console.log(s1 === s2) // true

我们还可以通过Symbol.keyFor反向导出Symbol.for传入的值




let s2 = Symbol.for('chenying')
console.log(Symbol.keyFor(s2)) // 可以反向导出Symbol.for中的描述符chenying

# 类数组转为真数组

日常开发中我们经常会将一些类数组转为真数组,常见的有2种用法




 


function ajax() {
    // 1.console.log(Array.from(arguments))
    // 2.console.log([...arguments])
}
ajax('url', 'get')

这里主要深入理解一下Array.from()[...xx]的区别

首先Array.from()是通过元素中的length的值来遍历元素然后往数组里面添加元素,如




console.log(Array.from({0: 1, 1: 2, length: 2})) // [1,2]
console.log(Array.from({0: 1, 1: 2})) // []

[...xx]内部是通过迭代器来实现的,它要求元素必须有Symbol.iterator有素,如



console.log([...{0:1, 1:2,length:2 }]) // TypeError: console.log is not iterable

但是我们可以手动的添加Symbol.iterator就可以实现对应的效果啦




 





console.log([...{
    0: 1, 1: 2, length: 2, [Symbol.iterator]: function* () {
        let i = 0
        while (this.length !== i) {
            yield this[i++]
        }
    }
}]) // [1, 2]

最后提一嘴,for of也是通过迭代器的原理来实现的,所以它不可以遍历对象,只可以遍历数组,因为对象没有Symbol.iterator