Understanding ECMAScript 6 閱讀問題小記

拖了一年說要看這本書,一直都沒堅持下來,開個 bo 記錄下以爲疑惑的問題,也算鞭策一下本身。正則表達式

 

第一章 塊級綁定算法

1. 第一章「塊級綁定」下,說 const 變量若是綁定的是對象 Object,那麼修改裏面的值是允許的。這個緣由是 const 阻止的是綁定的修改,而不是綁定值的修改。express

原文:const prevents modification of the binding, not modification of the bound value.數組

什麼叫作綁定?什麼叫作綁定值?跟內存地址有關?函數

 

2.  描述 let 和 const 聲明的變量爲什麼在聲明前不可訪問的現象時常常用到的術語 —— 暫存性死區(Temporary  Dead Zone)this

 

3. ES6以前解決循環中調用循環索引的問題是用即時調用函數表達式(immediately-invoked function express,IIFEs)編碼

有哪些 IIFE 的例子?爲何用 IIFE 能夠保證每次循環索引不共用?spa

 

第二章 字符串和正則表達式調試

1. charCodeAt() 和 codePointAt()rest

ES6 以前,Javascript 的字符串用的 UCS-2(如今已經合併爲UTF-16)字符編碼,也就是用 16位的二進制序列來表明一個字符,這個序列稱爲一個 code unit(碼元),它的取值範圍是 \u0000 - \uFFFF,其中,從 \uD800 - \uDFFF 是空段,這個範圍內的序列沒法表示可視字符。以前 Javascript 的字符串 length,charAt 都是以 code unit 爲單位計算的。

可是隨着 Unicode 字符集愈來愈大,光是一個 code unit 沒辦法表明全部的字符了,因此就擴展到能夠用兩個 code unit 來表明一個字符,也就是用 32 位二進制序列來表明字符,取值範圍是 \u010000 - \u10FFFF,在這種狀況下,第一個 code unit 稱爲高位(high surrogate)字符,取值範圍是 [\uD800, \uDBFF],第二個 code unit 稱爲低位(low surrogate)字符,取值範圍是 [\uDC00, \uDFFF]。因此這樣用 charCodeAt 去肯定一個由兩個 code unit 組成的字符,就只能獲得高位或低位 code unit 的 code point(碼點),此時由它們的取值範圍可知,獲得的都是不可視字符,因此要拿到由兩個 code unit 組成的字符,不能用 charCodeAt,要用 codePointAt。

下面是一對高位低位 code unit (高位取值 [\uD800, \uDBFF],低位取值 [\uDC00, \uDFFF])與 一個正式的 code point(取值 [\u010000, \u10FFFF])的轉換函數,這個算法是以前已經規定的。

function getCodePair(CodePoint) {  
  let highSurrogate = Math.floor((CodePoint - 0x10000) / 0x400) + 0xD800;
  let lowSurrogate = (CodePoint - 0x10000) % 0x400 + 0xDC00;
  return [highSurrogate, lowSurrogate];
}
getCodePair(0x1F600); // => [0xDC00, 0xDFFF]

function getCodePoint(highSurrogate, lowSurrogate) {  
  return (highSurrogate - 0xD800) * 0x400 + lowSurrogate - 0xDC00 + 0x10000;
}
getCodePoint(0xD83D, 0xDE00); // => 0x1F600

注:由於只爲本身理解,因此有些概念沒有提到,好比說基礎面 BMP,輔助面等等,以後可能會補充……

因此要判斷一個字符包含一個 code unit 仍是 兩個 code unit,能夠直接用 codePointAt() 判斷返回值是否大於 \uFFFF,大於的話就是由兩個 code unit 組成的了。

 

2. 標籤化模板(Tagged Template),也就是可以根據本身須要調整模板字符串的輸出結果。所需材料:一個模板字面量,一個標籤模板。

模板字面量,就是用 ` 包括的一個字符串,裏面能夠帶有替代位,也就是被 ${ 和 } 包括的字符串,這個字符串是替代位要填入的變量名,好比 `${name} is a fan of KinKi Kids` 這一個模板字面量裏,name 是要填入這個替代位的變量名;

一個標籤模板,就是一個函數,其第一個參數是字面量數組,包括了被替代位分隔開的固定字符串,其中第一個元素必定是第一個替代位以前的字符串,即便像上面這個字符串裏替代位前面是空串,也要把這個空串放到第一位,同理,不管最後一個替代位後面是否是空串,都要將它放到最後一個元素裏;剩餘參數是不定形式,方便靈活處理。這樣,字面量數組的長度必定會比替代位數組的長度多 1,在交替處理字面量和替代位的時候,循環時用替代位的長度做爲限制,就能夠保證不會越界。

標籤模板函數的格式以下:

function tag(literals, ...substitutions) {
  // 處理字面量等,返回字符串。literals 是字面量,substitutions 是替代位
}

要調用標籤模板的時候,這樣作,tag 是標籤模板的函數名:

let message = tag`Hello World`;

 

第三章 函數

1. 剩餘參數(rest parameters)

爲了處理未命名參數之外的參數,好比對 function a(param1, param2),調用時傳入了 a(1, 2, 3, 4, 5),那麼參數中的 1 和 2 對應 params1 和 params2,後面的 三、四、5 是沒有參數名對應的。ES6 以前使用 arguments 數組來包括全部的參數,包括前面已經命名的參數,這樣須要肯定從哪一個下標開始是未命名參數。

爲了解決獲取未命名參數不方便的問題,ES6 添加了剩餘參數的概念,用三個點(...)和緊跟在後面的命名參數一塊兒表明,如 function a(param1, param2, ...keys) 裏的 keys 就是一個剩餘參數,這是一個數組,裏面包含了全部未命名的參數。

要注意的是,1)每一個函數只能有一個剩餘參數,而且不能在剩餘參數後面再添加其餘命名參數,2)不能在對象字面量的 setter 屬性中用剩餘參數。

對象字面量的 setter 屬性?

 

2. 爲何對 Math.max 等已經定義的函數能夠經過 (...values, param1) 的方法調用?好比 Math.max(...[-1, -2, -3], 0) 能夠輸出 0?

這個狀況下,(...)就是一個擴展運算符,加在要傳進函數的數組前面,這樣 Javascript 引擎會把數組的內容分割爲單個參數傳入函數,對於 Math.max(...[-1, -2, -3]),它跟 Math.max(-1, -2, -3) 是等價的。

同時這種狀況下,表明擴展運算符的(...)是不限制數量的,即 Math.max(...[1, 3, 4, 7], 0, ...[33, 44, 55]) 也是合法的,能夠混用數組和單個變量。

 

3. ES6 新添加的函數 name 屬性只是爲了讓工程師在調試的時候可以獲取到有用信息,不可濫用。getter 與 setter 函數的 name 都必須用 Object.getOwnPropertyDescriptor() 來檢索,對於 getter 或 setter,他們的 name 都會帶上 get 或 set,好比對 get firstName(),它的 name 就是 'get firstName'。

 

4. 塊級函數 v.s. let 變量函數

以前第一章說道過,在塊級做用域裏,let 定義的變量在賦予初始值以前使用 typeof 是會報錯的,由於此時的 let 變量還在暫存性死區,不存在變量提高的概念;而塊級函數可以進行變量提高,也就是在定義具體的函數內容前使用 typeof 或相似的命令時,也是不會報錯的。在這種對比下,能夠根據需不須要做變量提高,酌情選擇使用塊級函數或 let 變量函數。

如下是塊級函數:

if (true) {
  // 這是一個塊級做用域
  console.log(typeof dosth);  // 'function'
  // 塊級函數
  function dosth() {
    // ....
  }
}

如下是 let 變量函數:

if (true) {
  // 這是一個塊級做用域
  console.log(typeof func);  // 報錯!
  // let 變量函數
  let func = function() {
    // ....
  }
}

注意:此處都沒有用到嚴格模式,在非嚴格模式下,塊級函數會變量提高到全局環境中;在嚴格模式下,塊級函數會提高到塊級做用域中。這是兩種模式的細微差異。

 

5. 箭頭函數沒有本身的 this、arguments、super 之類的,只可以經過做用域鏈向上尋找最近的非箭頭函數。

可是在「沒有 arguments 綁定」那一節對例子的講解沒有徹底理解,提到了 「arrowFunction 再也不建立其的函數的做用域內,但因爲 arguments 標識符的做用域解析,arguments 對象依然可被訪問」,裏面提到的做用域概念仍是有點模模糊糊的?

 

第四章 擴展的對象功能

1. 什麼是 super ?什麼是訪問器屬性

 

2. 爲何用 super 訪問原型對象的屬性時,只能用簡寫?若是在 function() { /* ... */ } 的註釋部分使用 super 會報錯……

跟 super 相關的內容一頭霧水 2333

相關文章
相關標籤/搜索