Es6筆記

前言

筆記僅記錄了相比於第一次學習,重新理解的知識點
完整內容詳見:《ECMAScript 6 入門》 阮一峯

總結

經歷兩個星期結合ES6的React實踐,決定再回頭看一遍阮一峯的ES6教程,發現收穫多多,常看常新。
第一遍看時,比較敷衍,沒有實踐自然也理解不深,綜合來說,阮一峯的教程更適合查漏補缺,而不是作爲入門教材。

索引

  1. 解構賦值的用途
  2. 尾調用優化
  3. 擴展運算符的用途
  4. 數組的方法擴展
  5. 對象
  6. Set類型 : distinct Array
  7. Map類型:可擴展鍵名,值—值對
  8. Proxy對象
  9. Promise對象
  10. Iterator 迭代器
  11. Generator生成器
  12. async函數
  13. 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值,默認都爲true
jQuery.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對象

① 封裝了一個函數
② 對內部函數返回的resolvereject進行分發處理(.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);
yield實例運行的console結果
yield實例運行的console結果

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 類

① super
super(): 代表父類的構造函數傳入父類的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
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發佈了1 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章