深入理解 ES6

深入理解 ES6
编辑推荐
√ 不识老尼,枉为前端攻城狮,其成名作《JS 高级程序设计》曾名动江湖。
√ Redux 缔造者与 React 核心成员作序力荐,盛赞本书对 JS 的剖析无人企及。
√ 用直截了当的方式传达艰深的技术细节,对技术的理解方可高效送达。
√ 中高级开发者藉由本书可一举迈入对标准及其未来特性熟稔于心之化境。
内容简介
ES6 是 ECMAScript 标准十余年来变动大的一个版本,其中添加了许多新的语法特性,既有大家耳熟能详的 Promise,也有闻所未闻的 Proxy 代理和 Reflection 反射;既有可以通过转译器(Transpiler)等方式在旧版本浏览器中实现兼容的 let、const、不定参数、展开运算符等功能,亦有无论如何都无法实现向前兼容的尾调用优化。深入理解 ES6 的特性对于所有 JavaScript 开发者而言至关重要,在可预见的未来,ES6 中引入的语言特性会成为 JavaScript 应用程序的主流特性,这也是《深入理解 ES6》的初衷。希望你通过阅读《深入理解 ES6》可以了解 ES6 的新特性,并在需要时能够随时使用。
作者简介
Nicholas C. Zakas 自 2000 年以来一直致力于 Web 应用程序的开发,重点关注前端开发,并以写作和讲述前沿*实践而闻名。他曾于雅虎主页任职 5 年有余,他也是多本书的作者,其中包括 The Principles of Object-Oriented JavaScript(No Starch Press 出版社)和 Professional JavaScript for Web Developers(Wrox 出版社)。
关于技术评审
Juriy Zaytsev(在网上以 kangax 著称)是纽约的一位前端网站开发人员。自 2007 年以来,他一直在探索 JavaScript 的怪异特性并撰写相关文章。Juriy 为多个开源项目做出过贡献,其中包括 Prototype.js 和其他的热门项目,如他自己的 Fabric.js。他是按需定制打印服务 printio.ru 的共同创始人,目前任职于 Facebook。
刘振涛,腾讯前端工程师;infoQ 网站资深译者,负责重点连载专栏《深入浅出 ES6》;长期关注 Web 开发领域新生,尤其是 Ecma* 6;爱好摄影、网球,重度信息癖(Infomania)患者。
目录
第 1 章 块级作用域绑定 1
-
var 声明及变量提升(Hoisting)机制 1
-
块级声明 3
-
– let 声明 3
-
– 禁止重声明 4
-
– const 声明 4
-
– 临时死区(Temporal Dead Zone) 6
-
循环中的块作用域绑定 7
-
– 循环中的函数 8
-
– 循环中的 let 声明 9
-
– 循环中的 const 声明 10
-
全局块作用域绑定 12
-
块级绑定最佳实践的进化 13
-
小结 13
第 2 章 字符串和正则表达式 14
-
更好的 Unicode 支持 14
-
– UTF-16 码位 15
-
– codePointAt() 方法 16
-
– String.fromCodePoint() 方法 17
-
– normalize() 方法 17
-
– 正则表达式 u 修饰符 19
-
其他字符串变更 21
-
– 字符串中的子串识别 21
-
– repeat() 方法 22
-
其他正则表达式语法变更 23
-
– 正则表达式 y 修饰符 23
-
– 正则表达式的复制 26
-
– flags 属性 27
-
模板字面量 28
-
– 基础语法 28
-
– 多行字符串 29
-
– 字符串占位符 31
-
– 标签模板 32
-
小结 36
第 3 章 函数 37
-
函数形参的默认值 37
-
– 在 ECMAScript 5 中模拟默认参数 38
-
– ECMAScript 6 中的默认参数值 38
-
– 默认参数值对 arguments 对象的影响 40
-
– 默认参数表达式 42
-
– 默认参数的临时死区 44
-
处理无命名参数 46
-
– ECMAScript 5 中的无命名参数 46
-
– 不定参数 47
-
增强的 Function 构造函数 49
-
展开运算符 50
-
name 属性 52
-
– 如何选择合适的名称 52
-
– name 属性的特殊情况 52
-
明确函数的多重用途 54
-
– 在 ECMAScript 5 中判断函数被调用的方法 54
-
– 元属性(Metaproperty)new.target 55
-
块级函数 57
-
– 块级函数的使用场景 58
-
– 非严格模式下的块级函数 58
-
箭头函数 59
-
– 箭头函数语法 60
-
– 创建立即执行函数表达式 62
-
– 箭头函数没有 this 绑定 63
-
– 箭头函数和数组 65
-
– 箭头函数没有 arguments 绑定 66
-
– 箭头函数的辨识方法 66
-
尾调用优化 67
-
– ECMAScript 6 中的尾调用优化 68
-
– 如何利用尾调用优化 69
-
小结 71
第 4 章 扩展对象的功能性 72
-
对象类别 72
-
对象字面量语法扩展 73
-
– 属性初始值的简写 73
-
– 对象方法的简写语法 74
-
– 可计算属性名(Computed Property Name) 75
-
新增方法 76
-
– Object.is() 方法 76
-
– Object.assign() 方法 77
-
重复的对象字面量属性 80
-
自有属性枚举顺序 81
-
增强对象原型 82
-
– 改变对象的原型 82
-
– 简化原型访问的 Super 引用 83
-
正式的方法定义 86
-
小结 88
第 5 章 解构:使数据访问更便捷 89
-
为何使用解构功能 89
-
对象解构 90
-
– 解构赋值 91
-
– 默认值 92
-
– 为非同名局部变量赋值 93
-
– 嵌套对象解构 94
-
数组解构 96
-
– 解构赋值 97
-
– 默认值 99
-
– 嵌套数组解构 99
-
– 不定元素 99
-
混合解构 101
-
解构参数 102
-
– 必须传值的解构参数 103
-
– 解构参数的默认值 104
-
小结 106
第 6 章 Symbol 和 Symbol 属性 107
-
创建 Symbol 107
-
Symbol 的使用方法 109
-
Symbol 共享体系 110
-
Symbol 与类型强制转换 112
-
Symbol 属性检索 112
-
通过 well-known Symbol 暴露内部操作 113
-
– Symbol.hasInstance 方法 114
-
– Symbol.isConcatSpreadable 属性 116
-
– Symbol.match、Symbol.replace、Symbol.search 和 Symbol.split 属性 118
-
– Symbol.toPrimitive 方法 120
-
– Symbol.toStringTag 属性 122
-
– Symbol.unscopables 属性 125
-
小结 127
第 7 章 Set 集合与 Map 集合 128
-
ECMAScript 5 中的 Set 集合与 Map 集合 129
-
该解决方案的一些问题 129
-
ECMAScript 6 中的 Set 集合 131
-
– 创建 Set 集合并添加元素 131
-
– 移除元素 133
-
– Set 集合的 forEach() 方法 133
-
– 将 Set 集合转换为数组 136
-
– Weak Set 集合 136
-
ECMAScript 6 中的 Map 集合 139
-
– Map 集合支持的方法 140
-
– Map 集合的初始化方法 141
-
– Map 集合的 forEach() 方法 142
-
– Weak Map 集合 143
-
小结 147
第 8 章 迭代器(Iterator)和生成器(Generator) 149
-
循环语句的问题 149
-
什么是迭代器 150
-
什么是生成器 151
-
– 生成器函数表达式 153
-
– 生成器对象的方法 154
-
可迭代对象和 for-of 循环 155
-
– 访问默认迭代器 156
-
– 创建可迭代对象 157
-
内建迭代器 158
-
– 集合对象迭代器 158
-
– 字符串迭代器 163
-
– NodeList 迭代器 164
-
展开运算符与非数组可迭代对象 165
-
高级迭代器功能 166
-
– 给迭代器传递参数 166
-
– 在迭代器中抛出错误 168
-
– 生成器返回语句 170
-
– 委托生成器 171
-
异步任务执行 174
-
– 简单任务执行器 174
-
– 向任务执行器传递数据 176
-
– 异步任务执行器 177
-
小结 180
第 9 章 JavaScript 中的类 181
-
ECMAScript 5 中的近类结构 181
-
类的声明 182
-
– 基本的类声明语法 182
-
– 为何使用类语法 184
-
类表达式 186
-
– 基本的类表达式语法 186
-
– 命名类表达式 187
-
作为一等公民的类 189
-
访问器属性 190
-
可计算成员名称 192
-
生成器方法 193
-
静态成员 195
-
继承与派生类 196
-
– 类方法遮蔽 199
-
– 静态成员继承 199
-
– 派生自表达式的类 200
-
– 内建对象的继承 203
-
– Symbol.species 属性 205
-
在类的构造函数中使用 new.target 208
-
小结 210
第 10 章 改进的数组功能 211
-
创建数组 211
-
– Array.of() 方法 212
-
– Array.from() 方法 213
-
为所有数组添加的新方法 216
-
– find() 方法和 findIndex() 方法 217
-
– fill() 方法 217
-
– copyWithin() 方法 218
-
定型数组 219
-
– 数值数据类型 220
-
– 数组缓冲区 221
-
– 通过视图操作数组缓冲区 221
-
定型数组与普通数组的相似之处 228
-
– 通用方法 229
-
– 相同的迭代器 230
-
– of() 方法和 from() 方法 230
-
定型数组与普通数组的差别 231
-
– 行为差异 231
-
– 缺失的方法 232
-
– 附加方法 233
-
小结 234
第 11 章 Promise 与异步编程 235
-
异步编程的背景知识 235
-
– 事件模型 236
-
– 回调模式 236
-
Promise 的基础知识 239
-
– Promise 的生命周期 239
-
– 创建未完成的 Promise 242
-
– 创建已处理的 Promise 244
-
– 执行器错误 247
-
全局的 Promise 拒绝处理 248
-
Node.js 环境的拒绝处理 248
-
浏览器环境的拒绝处理 251
-
串联 Promise 253
-
– 捕获错误 254
-
– Promise 链的返回值 255
-
– 在 Promise 链中返回 Promise 256
-
响应多个 Promise 259
-
– Promise.all() 方法 259
-
– Promise.race() 方法 260
-
自 Promise 继承 262
-
基于 Promise 的异步任务执行 263
-
小结 267
第 12 章 代理(Proxy)和反射(Reflection)API 269
-
数组问题 269
-
代理和反射 270
-
创建一个简单的代理 271
-
使用 set 陷阱验证属性 272
-
用 get 陷阱验证对象结构(Object Shape) 274
-
使用 has 陷阱隐藏已有属性 275
-
用 deleteProperty 陷阱防止删除属性 277
-
原型代理陷阱 279
-
– 原型代理陷阱的运行机制 279
-
– 为什么有两组方法 281
-
对象可扩展性陷阱 282
-
– 两个基础示例 283
-
– 重复的可扩展性方法 284
-
属性描述符陷阱 285
-
– 给 Object.defineProperty() 添加限制 286
-
– 描述符对象限制 287
-
– 重复的描述符方法 288
-
ownKeys 陷阱 290
-
函数代理中的 apply 和 construct 陷阱 291
-
– 验证函数参数 292
-
– 不用 new 调用构造函数 294
-
– 覆写抽象基类构造函数 296
-
– 可调用的类构造函数 297
-
可撤销代理 298
-
解决数组问题 299
-
– 检测数组索引 300
-
– 添加新元素时增加 length 的值 300
-
– 减少 length 的值来删除元素 302
-
– 实现 MyArray 类 304
-
将代理用作原型 307
-
– 在原型上使用 get 陷阱 307
-
– 在原型上使用 set 陷阱 308
-
– 在原型上使用 has 陷阱 309
-
– 将代理用作类的原型 310
-
小结 314
第 13 章 用模块封装代码 315
-
什么是模块 315
-
导出的基本语法 316
-
导入的基本语法 317
-
– 导入单个绑定 318
-
– 导入多个绑定 318
-
– 导入整个模块 318
-
– 导入绑定的一个微妙怪异之处 320
-
导出和导入时重命名 320
-
模块的默认值 321
-
– 导出默认值 321
-
– 导入默认值 322
-
重新导出一个绑定 323
-
无绑定导入 324
-
加载模块 325
-
– 在 Web 浏览器中使用模块 325
-
– 浏览器模块说明符解析 329
-
小结 330
-
附录 A ECMAScript 6 中较小的改动 331
-
附录 B 了解 ECMAScript 7(2016) 337
-
索引 343