## 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']
```