## let 和 const
1、let 和 const声明的变量都是挂载在全局对象上的,var声明的变量挂载在顶层对象上面(浏览器环境即是window对象),目的是将全局对象和顶层对象分离。
2、都不存在变量提升。即变量使用前必须先声明。
3、都有暂时性死区,即在一个代码块儿中声明了的变量不受外界变量的影响。
```
let num = 10
if (true) {
console.log(num) // 代码会报错
let num = 5
}
```
4、块儿级作用域,没有这个概念之前,要想实现一个单独的命名空间必须使用立即执行函数(IIFE),现在只需要添加{}即可。
5、ES6声明变量的6中方法:
var、let、const、function(函数声明)、import、class
6、Object.freeze(obj)浅度冻结对象,不能修改、新增、删除属性
```
// 深度冻结对象及其属性
var constantize = (obj) => {
Object.freeze(obj)
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj\[key\] === 'object' ) {
constantize( obj\[key\] )
}
})
}
```
7、Object.seal(obj)封闭一个对象,阻止新增、删除属性,支持当前属性修改。
8、Object.assign(target, source)将所有可枚举的属性值从一个或多个源对象复制到目标对象。
```
let target = { id: '0' }
let source0 = { name: 'zhang' }
let source1 = { id: '1' }
let source2 = { sex: 'man' }
let final = Object.assign(target, source0, source1, source2) // { id: '1', name: 'zhang', sex: 'man' }
```
9、...source,对象扩展运算符将源对象中所有可遍历的属性,拷贝到当前对象中。任何Iterator接口的对象,都可以用扩展运算符转换成数组。
```
// 对象
let source0 = { id: '0' }
let target = { ...source0, id: '1' } // { id: '1' }
// 数组
let arr0 = [1, 2, 3]
let arr1 = [...arr0, 4] // [1, 2, 3, 4]
// 函数参数
let fn = function(a, b, c) { return a + b + c }
let arr0 = [1, 2, 3]
fn(...arr0) // 6
// 扩展运算符可以与解构赋值结合起来,用于生成数组(如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。)
let [frist, ...rest] = [1, 2, 3, 4, 5]
first // 1
rest // [2, 3, 4, 5]
// 扩展运算符还可以将字符串转为真正的数组
let arr0 = [...'str'] // ['s', 't', 'r']
```