拖了一年說要看這本書,一直都沒堅持下來,開個 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