前言
筆記僅記錄了相比於第一次學習,重新理解的知識點
完整內容詳見:《ECMAScript 6 入門》 阮一峯
總結
經歷兩個星期結合ES6的React實踐,決定再回頭看一遍阮一峯的ES6教程,發現收穫多多,常看常新。
第一遍看時,比較敷衍,沒有實踐自然也理解不深,綜合來說,阮一峯的教程更適合查漏補缺,而不是作爲入門教材。
索引
- 解構賦值的用途
- 尾調用優化
- 擴展運算符的用途
- 數組的方法擴展
- 對象
- Set類型 : distinct Array
- Map類型:可擴展鍵名,值—值對
- Proxy對象
- Promise對象
- Iterator 迭代器
- Generator生成器
- async函數
- Class 類
1. 解構賦值的用途
① 交換變量值: [x, y] = [y, x]
② 函數返回值的獲取更便利: let [a, b, c ] = func()
③ 函數無序傳參
有序傳參:function func([x,y,z]) { }
func([1,2,3])
無序傳參:function func({x, y, z}) { }
func({z: 3, y: 2 , x: 1})
④ 提取JSON數據更方便
⑤ 函數傳參可設置默認值,如預設Ajax請求的參數
當傳入Ajax請求的參數不聲明async與cache值,默認都爲truejQuery.ajax = function (url, { async = true, cache = true}) {};
⑥ Map類型取鍵名/值 : for ( let [key, value] of map) { }
⑦ 加載CommonJS模塊中的指定方法: import { func1 , func2 } from '../common.js'
2. 尾調用優化
在函數的最後一步(即return)中調用另一個函數,形如return g(a,b);
,叫做尾調用。
存儲於內存中的函數調用記錄(包含了調用內存位置、變量等信息),叫做調用幀,嵌套函數的調用幀形成了調用棧;這很浪費內存。
因此在return句中採用尾調用,當內層函數的調用不再用到外層函數中的信息,就可用最新內層函數的調用幀取代外層函數的調用幀,節省內存。
3. 擴展運算符的用途
① 取代concat()
合併數組: let arr = [...arr1, ...arr2];
② 與解構賦值並用,截取部分數組: let [item, ...rest] = array;
③ 分解對象類型的函數返回值: var { data, code, msg } = getData();
④ 字符串轉數組: [...'hello] 等同於 'hello'.split('');
⑤ 正確識別32位的Unicode字符串: [ ...str ].length 獲取unicode字符串正確長度
4. 數組的方法擴展
① array.find(function)
:查找第一個符合條件的數組元素
② array.findIndex()
:與indexOf功能相同,但findIndex優於可查找NaN元素
③ new Array(5).fill(0)
:創建數組並且初始化爲全0
④ 數組元素遍歷array.keys()
:遍歷鍵名array.values()
:遍歷鍵值array.entries()
:遍歷鍵值對
⑤ array.includes(value)
: 數組查找,可查找NaN
5. 對象
① let a = { [key]: value}
:用表達式作鍵名
② Object.is(value1, value2 )
: 嚴格一致,不會自動轉換類型,準確性高於“===”
③ Object.assign(target, obj1, obj2 )
: 合併對象屬性到第一個參數中;是淺拷貝(符合類型爲引用)
④ object.__proto__屬性
指向Object.prototype屬性
object.__proto__屬性
推薦使用的三個操作方法:
Object.setPrototypeOf(object, prototype)
Object.getPrototypeOf(obj);
Object.create()
⑤ prototype
與__proto__
屬性Array.prototype
:Array原型的所有方法new Array(3).__proto__
: 原型實例的自有屬性方法,內包含了Array.prototype中的所有方法
⑥ 對象的擴展:let { x, y, ...z } = { x: 1, y: 2, a: 3 , b: 4} ; 則 z = { a: 3 , b: 4 }
6. Set類型 : distinct Array
① .add()
② .size
③ .delete()
④ .has(value)
⑤ .clear()
⑥ Set轉數組: Array.from(set)
數組去重: Array.from (new Set(array))
7. Map類型:可擴展鍵名,值—值對
① .size
② .set(key, value)
③ .get(key)
④ .has(key)
⑤ .delete(key)
⑥ .clear()
⑦ 遍歷的順序即插入的順序
⑧ Map轉數組: ...map
8. Proxy對象
進程與對象實體之間的攔截層
9. Reflect對象
用於部署對象的新方法;可以通過Reflect對象拿到語言內部的方法,如Object.defineProperty
10. Promise對象
① 封裝了一個函數
② 對內部函數返回的resolve
與reject
進行分發處理(.then
與.catch
)
③ Promise新建後,立即執行
11. Iterator 迭代器
① Iterator.next()
的返回值: {value: 'value', done: false}
或 { value: undefined, done: true}
② 悄悄調用了可遍歷數據的Iterator的情況:
解構賦值有序對象(數組、set)、
擴展運算符...
、
yield* 表達式: yield* [2,3,4] 等同於 yield 2; yield 3; yield 4;
③ let ... in
:遍歷鍵名
④ let ... of
:遍歷鍵值(適用於有Iterator接口的數據)
12. Generator生成器
① 相當於一個封裝了多個狀態的狀態機
② 作用:生成並且返回一個遍歷器對象
③ 調用後並不立即執行,而是返回一個指向內部狀態的指針對象(遍歷器對象)
④ 調用iterator.next()
,纔是真正執行內部函數的時機
⑤ yield
可以嵌入普通語句中,但要放在圓括號中: console.log( 'hello' + (yield 123) );
⑥ yield表達式本身的返回值是undefined
,但可以用next(value)對上一個yield表達式賦值
⑦ yield * generator()
:在一個生成器函數中調用另一個生成器函數
⑧ 封裝異步函數,實現回調
function* demo () {
// do something Part1
yield go(); // 相當於分離了異步的兩個階段,part1與part2
// do something Part2
}
let g = demo();
g.next(); // 執行part1
g.next(); // part1執行完之後,再執行part2
⑨ 重點理解:
Generator 函數是分段執行的,yield表達式是暫停執行的標記,而next方法可以恢復執行。
在第一次調用.next()
時,執行到yield
語句(yield語句本身也被執行)。等下一次next調用,執行下一段包含yield
語句的代碼段。
function* demo () {
do thing 1
yield y1;
<---第一次執行next,執行到此處---->
do thing 2
yield y2;
<---第二次執行next,執行到此處---->
do thing 3
yield y3;
<---第三次執行next,執行到此處---->
do thing 4
yield y4;
<---第四次執行next,執行到此處---->
}
// 代碼實例
var a = 0;
function* demo() {
console.log('in demo a = 3')
console.log(yield a=3);
console.log('in demo a = 4')
console.log(yield a=4);
console.log('in demo a = 5')
console.log(yield a=5);
}
let g = demo();
console.log('首次next');
console.log(a);
console.log( g.next());
console.log(a);
console.log('二次next')
console.log(a);
console.log( g.next())
console.log(a);
console.log('三次next')
console.log(a);
console.log( g.next())
console.log(a);
13. async函數
是generator的語法糖,簡化了異步操作。相比generator,async具有以下優點:
① 內置執行器,單行調用即可完成generator函數的所有.next()
② 更具有語義性
③ 適用性更廣
yield命令:只能後跟 Thunk 或Promise
await命令:可後跟Promise對象與原始值
④ async函數的返回值是Promise對象
async將generator返回的Iterator對象自動執行後,並將結果封裝爲一個Promise對象,便於後期處理。return await 123;
==> 轉爲resolve狀態的Promise對象
async中return語句返回值,傳入.then()
作回調參數。return Promise.reject('出錯了');
==> 轉爲reject狀態的Promise對象
async中拋出錯誤,返回reject狀態的Promise對象,傳入.catch()
方法
⑤ forEach中的async是併發操作的,應該改用for循環
// 不推薦用forEach寫法
function dbFuc(db) { //這裏不需要 async
let docs = [{}, {}, {}];
// 可能得到錯誤結果
docs.forEach(async function (doc) {
await db.post(doc);
});
}
// 推薦用for循環
async function dbFuc(db) {
let docs = [{}, {}, {}];
for (let doc of docs) {
await db.post(doc);
}
}
14. Class 類
① supersuper()
: 代表父類的構造函數傳入父類的this,等同於Class.prototype.constructor.call(this)
super
:指向父類的原型對象,等同於Class.prototype
,可用於調用父類的靜態方法
② prototype
與__proto__
子類的__proto__
指向父類
,表示構造函數的繼承子類的prototype.__proto__
指向父類的prototype
屬性, 表示方法的繼承子類實例的__proto__.__proto__
指向父類實例的__proto__屬性
作者:daisimin7
鏈接:http://www.jianshu.com/p/b1a07c84c8eb
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。