拖了一年说要看这本书,一直都没坚持下来,开个 bo 记录下觉得疑惑的问题,也算鞭策一下自己。

第一章 块级绑定

1. 第一章“块级绑定”下,说 const 变量如果绑定的是对象 Object,那么修改里面的值是容许的。这个原因是 const 阻止的是绑定的修改,而不是绑定值的修改。

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

什么叫做绑定?什么叫做绑定值?跟内存地址有关?

2.  描述 let 和 const 声明的变量为何在声明前不可访问的现象时经常用到的术语 —— 暂存性死区(Temporary  Dead Zone)

3. ES6之前解决循环中调用循环索引的问题是用即时调用函数表达式(immediately-invoked function express,IIFEs)

有哪些 IIFE 的例子?为什么用 IIFE 可以保证每次循环索引不共用?

第二章 字符串和正则表达式

1. charCodeAt() 和 codePointAt()

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])的转换函数,这个算法是之前已经规定的。

  1. function getCodePair(CodePoint) {
  2. let highSurrogate = Math.floor((CodePoint - 0x10000) / 0x400) + 0xD800;
  3. let lowSurrogate = (CodePoint - 0x10000) % 0x400 + 0xDC00;
  4. return [highSurrogate, lowSurrogate];
  5. }
  6. getCodePair(0x1F600); // => [0xDC00, 0xDFFF]
  7.  
  8. function getCodePoint(highSurrogate, lowSurrogate) {
  9. return (highSurrogate - 0xD800) * 0x400 + lowSurrogate - 0xDC00 + 0x10000;
  10. }
  11. 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,在交替处理字面量和替代位的时候,循环时用替代位的长度作为限制,就可以保证不会越界。

标签模板函数的格式如下:

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

要调用标签模板的时候,这样做,tag 是标签模板的函数名:

  1. let message = tag`Hello World`;

第三章 函数

1. 剩余参数(rest parameters)

为了处理未命名参数以外的参数,比如对 function a(param1, param2),调用时传入了 a(1, 2, 3, 4, 5),那么参数中的 1 和 2 对应 params1 和 params2,后面的 3、4、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 变量函数。

以下是块级函数:

  1. if (true) {
  2. // 这是一个块级作用域
  3. console.log(typeof dosth); // 'function'
  4. // 块级函数
  5. function dosth() {
  6. // ....
  7. }
  8. }

以下是 let 变量函数:

  1. if (true) {
  2. // 这是一个块级作用域
  3. console.log(typeof func); // 报错!
  4. // let 变量函数
  5. let func = function() {
  6. // ....
  7. }
  8. }

注意:此处都没有用到严格模式,在非严格模式下,块级函数会变量提升到全局环境中;在严格模式下,块级函数会提升到块级作用域中。这是两种模式的细微差别。

5. 箭头函数没有自己的 this、arguments、super 之类的,只能够通过作用域链向上寻找最近的非箭头函数。

但是在“没有 arguments 绑定”那一节对例子的讲解没有完全理解,提到了 “arrowFunction 不再创建其的函数的作用域内,但由于 arguments 标识符的作用域解析,arguments 对象依然可被访问”,里面提到的作用域概念还是有点模模糊糊的?

第四章 扩展的对象功能

1. 什么是 super ?什么是访问器属性?

2. 为什么用 super 访问原型对象的属性时,只能用简写?如果在 function() { /* ... */ } 的注释部分使用 super 会报错……

跟 super 相关的内容一头雾水 2333

Understanding ECMAScript 6 阅读问题小记的更多相关文章

  1. understanding ECMAscript 6 ---- block bindings

    Traditionally, the way variable declarations work has been one tricky part of programming in javascr ...

  2. [译]Understanding ECMAScript 6 说明

    说明 JavaScript核心语言功能定义在ECMA-262中,此标准定义的语言是ECMAScript,浏览器中的JavaScript和Node.js环境是它的超级.当浏览器与Node.js想要通过额 ...

  3. [译]Understanding ECMAScript 6 内容目录

    说明 浏览器与Node.js兼容 这本书是写给谁的 概述 帮助与支持 基本知识 更好的Unicode支持 其他字符串变化 其他正则表达式变化 Object.is() 块绑定 解构赋值 数字 总结 函数 ...

  4. ECMAScript 6十大特性

    ES6入门 http://es6.ruanyifeng.com/ ES6排名前十的最佳特性列表 Default Parameters(默认参数) in ES6 Template Literals (模 ...

  5. My ECMAScript 7 wishlist

    With ECMAScript 6 now feature complete, any further changes to the core of JavaScript will happen in ...

  6. 前端资料QQ群交流

    转:https://github.com/jsfront/src/blob/master/qq.md 这本来是我QQ群内部的一份公共约定的日常交流规则,后来得到大伙的一致认可,并用实际行动来捍卫它,使 ...

  7. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  8. 如何成为一个伟大的 JavaScript 程序员

    这篇文章主要概述在我5年工作经验的基础上,我成为优秀JavaScript开发人员所使用的技术和资源. 当前大多数Web开发人员面临着这样一个共同的问题:他们必须在多个不同的领域领先于他人——从数据库到 ...

  9. 初探ECMAScript6

    基础变化 String类型新增了三个方法,不必使用indexOf来判断一个字符串是否在另一个字符串内 //String changes var a = "Hello world"; ...

随机推荐

  1. tar.xz问价解压

    1. 解压tar.xz安装包 今天去Ubuntu上安装nodejs,下载的文件是node-v8.11.1-linux-x64.tar.xz,这是两层压缩,外面是xz压缩,里层是tar压缩,所以分两步实 ...

  2. tab栏切换效果运用案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Python 进程之间共享数据(全局变量)

    进程之间共享数据(数值型): import multiprocessing def func(num): num.value=10.78 #子进程改变数值的值,主进程跟着改变 if __name__= ...

  4. MySQL之Foreign_Key

    MySQL之Foregin_Key 一\\一对多 一.员工表和部门表 dep emp 类似与我们将所有的代码都写在一个py文件内 确立标语表之间的关系 思路:一定要要换位思考问题(必须两方都考虑周全之 ...

  5. oracle给用户赋dblink权限

    create database link 别名(可任意起) connect to 需要连接库的用户名identified by 需要连接库的用户名 using '(DESCRIPTION =(ADDR ...

  6. fpga延时程序编写

    //工匠小建 延时计数 100微妙计数 50M*0.00001-1 (个人理解:1s中50M次动作.那么100us多少次动作.做完这些动作就是延时)parameter delay_100us=16'd ...

  7. CSS初识

    CSS:层叠样式表,控制网页数据样式显示,使得数据的表现和内容分离 CSS的引入方式 使用元素内嵌样式表:例<a style=”font-size:40px”></a>表示在a ...

  8. quartz 时间配置

    Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知) 时间格式: <!-- s m h d m w(?) y( ...

  9. Flask【第4篇】:用Flask的扩展实现的简单的页面登录

    用flask的扩展实现的简单的页面登录 from flask import Flask,render_template,request,redirect,session app = Flask(__n ...

  10. MAN RPM

    RPM(8)   Red Hat Linux   RPM(8) NAME/名称       rpm - RPM Package Manager/RPM-RPM包管理器SYNOPSIS/简介  QUER ...