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

相关文章
相关标签/搜索