阮師傅的ES6教程整理下來的;
- ES、JS關系
- JS 1996年 Netscape創立,並交ECMA標準化;
- ECMA-262 規定瀏覽器腳本語言標準,ECMAScript 1.0;
- ES 是 JS 的規格,JS 是 ES 的實現;
- ES6、ES2015關系
- ES2015 - ES6、ES2016 - ES6.1、ES2017 - ES6.2;
- 下壹代JS語言;
- 語法提案
- 向TC39標準委員會提交;
- GitHub.com/tc39/ecma262;
- Stage 0-Strawman、1-Proposal、2-Draft、3-Candidate、4-Finished;
- 歷史
- ECMAScript 1.0 - 1997年,2.0-1998年6月,3.0-1999年12月(入門);
- 2007、2008年,ES4因激進大部分內容沒有通過(產生ES3.1 代號Harmony),ES6制定起點是2000年;
- 2009年12月ES5.0,Harmony 分裂,JavaScript.next 演變 ES6;
- ···
let、const
let
- 代碼塊內有效;
- for 設置循環處是代碼塊內的父作用域;
- 不存在變量提升;
- 暫時性死區(temporal dead zone,TDZ);
- typeof 不再安全;
- ReferenceError 拋錯;
- 不允許重復聲明;
塊級作用域
- ES5 只有全局和函數作用域;
- 為什麼需要?
- 內層變量可能會覆蓋外層變量;
- 用來計數的循環變量泄露為全局變量;
- 外層代碼塊不受內層代碼塊的影響;
- ES6 允許塊級作用域的任意嵌套;
- 廣泛應用的匿名立即執行函數表達式(匿名 IIFE)不再必要了;
- ES6 規定,塊級作用域之中,函數聲明語句的行為類似於
let
,在塊級作用域之外不可引用; - ES6 的塊級作用域必須有大括號,如果沒有大括號,JavaScript 引擎就認為不存在塊級作用域;
'use strict'
嚴格模式下,函數只能聲明在當前作用域的頂層- 區分:函數聲明、函數表達式的區別
const
聲明不賦值會拋錯:
SyntaxError: Missing initializer in const declaration
;同let壹樣塊級區域有效、存在暫時性死區;
並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動;
簡單類型不得改動,復合類型數據,變量指向的內存地址,保存的只是壹個指向實際數據的指針,
const
只能保證這個指針是固定的(即總是指向另壹個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。應該使用
Object.freeze
方法,凍結對象;徹底凍結
`
javascript
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
});if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); }
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- ES聲明變量有6種方法;
- 頂層對象
- 瀏覽器:window
- Node:global
- ES6 為了改變這壹點,壹方面規定,為了保持兼容性,`var`命令和`function`命令聲明的全局變量,依舊是頂層對象的屬性;另壹方面規定,`let`命令、`const`命令、`class`命令聲明的全局變量,不屬於頂層對象的屬性。也就是說,從 ES6 開始,全局變量將逐步與頂層對象的屬性脫鉤。
- ES2020 規定了 globalThis
## 解構
- 數組解構
- 只要某種數據結構具有 Iterator 接口,都可以采用數組形式的解構賦值。
- 默認值:解構允許指定默認值,ES6 內部使用嚴格相等運算符(`===`),判斷壹個位置是否有值。所以,只有當壹個數組成員嚴格等於`undefined`,默認值才會生效;
- ```javascript
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
如果默認值是壹個表達式,那麼這個表達式是惰性求值的;
對象解構
- 數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值;
- 如果解構失敗,變量的值等於
undefined
; let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
如果變量名與屬性名不壹致,必須寫成這樣,對象的解構賦值的內部機制,是先找到同名屬性,然後再賦給對應的變量。真正被賦值的是後者,而不是前者(前者為模式,後者是變量);- 對象的解構賦值可以取到繼承的屬性;
- 對象的解構也可以指定默認值;
- 註意點:
- 如果要將壹個已經聲明的變量用於解構賦值,大括號會被理解為代碼塊;
- 解構賦值允許等號左邊的模式之中,不放置任何變量名;
- 由於數組本質是特殊的對象,因此可以對數組進行對象屬性的解構;
字符串的解構賦值;
undefined、null 無法解構;
用途
- 交換變量的值
- 從函數返回多個值
- 函數參數的定義
- 提取 JSON 數據
- 函數參數的默認值
- 遍歷 Map 結構
- 任何部署了 Iterator 接口的對象,都可以用
for...of
循環遍歷
- 任何部署了 Iterator 接口的對象,都可以用
- 輸入模塊的指定方法
字符串擴展
Unicode
Unicode 可以使用大括號
\u{20BB7}
表示更多字符`
javascript
‘\u{1F680}’ === ‘\uD83D\uDE80’ // true1
2
3
4
5
6
7
- ```javascript
'\z' === 'z' // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true
字符串遍歷
- ES6 字符串 有 Iterator 遍歷接口 可以被 for of 循環遍歷;
- 可以識別大於
0xFFFF
的碼點;
U+2028、U+2029
- JavaScript 規定有5個字符,不能在字符串裏面直接使用,只能使用轉義形式:
- U+005C:反斜杠(reverse solidus)
- U+000D:回車(carriage return)
- U+2028:行分隔符(line separator)
- U+2029:段分隔符(paragraph separator)
- U+000A:換行符(line feed)
- 字符串裏面不能直接包含反斜杠,壹定要轉義寫成
\\
或者\u005c
- JavaScript 規定有5個字符,不能在字符串裏面直接使用,只能使用轉義形式:
JSON.stringify
- ES2019 改變了
JSON.stringify()
的行為。如果遇到0xD800
到0xDFFF
之間的單個碼點,或者不存在的配對形式,它會返回轉義字符串,留給應用自己決定下壹步的處理;
- ES2019 改變了
字符模版 `
- 普通字符串;
- 多行字符串;
- 嵌入變量;
- trim 消除首尾換行;
- 模板字符串甚至還能嵌套;
標簽模版 Tagged template
- func`abc ${123} 123`
- func([‘abc ‘,’ 123’],123)
- 用於 i18n 或者 過濾HTML
- 有 raw 屬性
模版字符限制
… 未完