编辑推荐

适读人群:JavaScript领域研究人员,前端开发人员

√横跨ES2015/2016/2017新标,抢占JavaScript制高点
√由千万级名博、布道引航无数前端入行的阮一峰执笔
√来自BAT一线实践,精彩案例透彻解读新标|保留语法
√新标首著,凝结多年研究心得,剖析ES理解应用难题

内容简介

ES6是下一代JavaScript语言标准的统称,每年6月发布一次修订版,迄今为止已经发布了3个版本,分别是ES2015、ES2016、ES2017。《ES6标准入门(第3版)》根据ES2017标准,详尽介绍了所有新增的语法,对基本概念、设计目的和用法进行了清晰的讲解,给出了大量简单易懂的示例。《ES6标准入门(第3版)》为中级难度,适合那些已经对JavaScript语言有一定了解的读者,可以作为学习这门语言全新进展的工具书,也可以作为参考手册供大家随时查阅新语法。第3版增加了超过30%的内容,完全覆盖了ES2017标准,相比第2版介绍了更多的语法点,还调整了原有章节的文字表达,充实了示例,论述更准确,更易懂易学。

作者简介

阮一峰,资深JavaScript语言专家,知名技术博客作者,专注于网站开发技术十余年。畅销书《黑客与画家》《软件随想录》的译者,现就职于蚂蚁金服集团。

目录

第1章ECMAScript6简介1
1.1ECMAScript和JavaScript的关系1
1.2ES6与ECMAScript2015的关系1
1.3语法提案的批准流程2
1.4ECMAScript的历史3
1.5部署进度4
1.6Babel转码器4
1.6.1配置文件.babelrc5
1.6.2命令行转码babel-cli6
1.6.3babel-node7
1.6.4babel-register8
1.6.5babel-core8
1.6.6babel-polyfill9
1.6.7浏览器环境10
1.6.8在线转换10
1.6.9与其他工具的配合11
1.7Traceur转码器11
1.7.1直接插入网页12
1.7.2在线转换13
1.7.3命令行转换14
1.7.4Node环境的用法15
第2章let和const命令17
2.1let命令17
2.1.1基本用法17
2.1.2不存在变量提升19
2.1.3暂时性死区19
2.1.4不允许重复声明21
2.2块级作用域22
2.2.1为什么需要块级作用域22
2.2.2ES6的块级作用域23
2.2.3块级作用域与函数声明24
2.2.4do表达式27
2.3const命令28
2.3.1基本用法28
2.3.2本质29
2.3.3ES6声明变量的6种方法30
2.4顶层对象的属性30
2.5global对象31
第3章变量的解构赋值33
3.1数组的解构赋值33
3.1.1基本用法33
3.1.2默认值35
3.2对象的解构赋值37
3.3字符串的解构赋值41
3.4数值和布尔值的解构赋值41
3.5函数参数的解构赋值42
3.6圆括号问题43
3.6.1不能使用圆括号的情况43
3.6.2可以使用圆括号的情况44
3.7用途44
第4章字符串的扩展49
4.1字符的Unicode表示法49
4.2codePointAt()50
4.3String.fromCodePoint()52
4.4字符串的遍历器接口52
4.5at()53
4.6normalize()53
4.7includes()、startsWith()、endsWith()54
4.8repeat()55
4.9padStart()、padEnd()56
4.10模板字符串57
4.11实例:模板编译60
4.12标签模板62
4.13String.raw()67
4.14模板字符串的限制68
第5章正则的扩展71
5.1RegExp构造函数71
5.2字符串的正则方法72
5.3u修饰符72
5.4y修饰符74
5.5sticky属性77
5.6flags属性77
5.7s修饰符:dotAll模式78
5.8后行断言79
5.9Unicode属性类80
5.10具名组匹配81
5.10.1简介81
5.10.2解构赋值和替换82
5.10.3引用83
第6章数值的扩展85
6.1二进制和八进制表示法85
6.2Number.isFinite()、Number.isNaN()86
6.3Number.parseInt()、Number.parseFloat()87
6.4Number.isInteger()88
6.5Number.EPSILON88
6.6安全整数和Number.isSafeInteger()89
6.7Math对象的扩展92
6.7.1Math.trunc()92
6.7.2Math.sign()92
6.7.3Math.cbrt()93
6.7.4Math.clz32()94
6.7.5Math.imul()95
6.7.6Math.fround()95
6.7.7Math.hypot()96
6.7.8对数方法96
6.7.9双曲函数方法98
6.8Math.signbit()98
6.9指数运算符99
6.10Integer数据类型99
6.10.1简介99
6.10.2运算100
第7章函数的扩展103
7.1函数参数的默认值103
7.1.1基本用法103
7.1.2与解构赋值默认值结合使用105
7.1.3参数默认值的位置107
7.1.4函数的length属性108
7.1.5作用域108
7.1.6应用111
7.2rest参数112
7.3严格模式113
7.4name属性115
7.5箭头函数116
7.5.1基本用法116
7.5.2注意事项118
7.5.3嵌套的箭头函数121
7.6绑定this123
7.7尾调用优化124
7.7.1什么是尾调用124
7.7.2尾调用优化125
7.7.3尾递归126
7.7.4递归函数的改写128
7.7.5严格模式129
7.7.6尾递归优化的实现129
7.8函数参数的尾逗号132
第8章数组的扩展133
8.1扩展运算符133
8.1.1含义133
8.1.2替代数组的apply方法134
8.1.3扩展运算符的应用136
8.2Array.from()139
8.3Array.of()142
8.4数组实例的copyWithin()143
8.5数组实例的find()和findIndex()144
8.6数组实例的fill()145
8.7数组实例的entries()、keys()和values()145
8.8数组实例的includes()146
8.9数组的空位147
第9章对象的扩展151
9.1属性的简洁表示法151
9.2属性名表达式154
9.3方法的name属性156
9.4Object.is()157
9.5Object.assign()158
9.5.1基本用法158
9.5.2注意点160
9.5.3常见用途161
9.6属性的可枚举性163
9.7属性的遍历165
9.8__proto__属性、Object.setPrototypeOf()、Object.getPrototypeOf()166
9.8.1__proto__属性166
9.8.2Object.setPrototypeOf()167
9.8.3Object.getPrototypeOf()168
9.9Object.keys()、Object.values()、Object.entries()169
9.9.1Object.keys()169
9.9.2Object.values()170
9.9.3Object.entries171
9.10对象的扩展运算符173
9.11Object.getOwnPropertyDescriptors()177
9.12Null传导运算符181
第10章Symbol183
10.1概述183
10.2作为属性名的Symbol185
10.3实例:消除魔术字符串188
10.4属性名的遍历189
10.5Symbol.for()、Symbol.keyFor()191
10.6实例:模块的Singleton模式192
10.7内置的Symbol值194
10.7.1Symbol.hasInstance194
10.7.2Symbol.isConcatSpreadable195
10.7.3Symbol.species196
10.7.4Symbol.match197
10.7.5Symbol.replace197
10.7.6Symbol.search198
10.7.7Symbol.split198
10.7.8Symbol.iterator199
10.7.9Symbol.toPrimitive200
10.7.10Symbol.toStringTag201
10.7.11Symbol.unscopables202
第11章Set和Map数据结构205
11.1Set205
11.1.1基本用法205
11.1.2Set实例的属性和方法207
11.1.3遍历操作208
11.2WeakSet212
11.2.1含义212
11.2.2语法212
11.3Map214
11.3.1含义和基本用法214
11.3.2实例的属性和操作方法218
11.3.3遍历方法220
11.3.4与其他数据结构的互相转换222
11.4WeakMap225
11.4.1含义225
11.4.2WeakMap的语法227
11.4.3WeakMap示例228
11.4.4WeakMap的用途229
第12章Proxy233
12.1概述233
12.2Proxy实例的方法237
12.2.1get()237
12.2.2set()241
12.2.3apply()243
12.2.4has()244
12.2.5construct()246
12.2.6deleteProperty()247
12.2.7defineProperty()248
12.2.8getOwnPropertyDescriptor()248
12.2.9getPrototypeOf()249
12.2.10isExtensible()249
12.2.11ownKeys()250
12.2.12preventExtensions()254
12.2.13setPrototypeOf()255
12.3Proxy.revocable()255
12.4this问题256
12.5实例:Web服务的客户端258
第13章Reflect259
13.1概述259
13.2静态方法261
13.3实例:使用Proxy实现观察者模式270
第14章Promise对象273
14.1Promise的含义273
14.2基本用法274
14.3Promise.prototype.then()278
14.4Promise.prototype.catch()279
14.5Promise.all()285
14.6Promise.race()287
14.7Promise.resolve()288
14.8Promise.reject()290
14.9两个有用的附加方法291
14.10应用292
14.11Promise.try()294
第15章Iterator和for...of循环297
15.1Iterator(遍历器)的概念297
15.2默认Iterator接口300
15.3调用Iterator接口的场合305
15.4字符串的Iterator接口307
15.5Iterator接口与Generator函数308
15.6遍历器对象的return()、throw()309
15.7for...of循环310
第16章Generator函数的语法317
16.1简介317
16.2next方法的参数323
16.3for...of循环325
16.4Generator.prototype.throw()328
16.5Generator.prototype.return()334
16.6yield*表达式335
16.7作为对象属性的Generator函数342
16.8Generator函数this342
16.9含义345
16.10应用347
第17章Generator函数的异步应用355
17.1传统方法355
17.2基本概念355
17.3Generator函数357
17.4Thunk函数361
17.5co模块368
17.6实例:处理Stream373
第18章async函数375
18.1含义375
18.2用法377
18.3语法379
18.4async函数的实现原理386
18.5其他异步处理方法的比较387
18.6实例:按顺序完成异步操作388
18.7异步遍历器390
第19章Class的基本语法399
19.1简介399
19.2严格模式403
19.3constructor方法403
19.4类的实例对象404
19.5Class表达式406
19.6不存在变量提升407
19.7私有方法408
19.8私有属性409
19.9this的指向410
19.10name属性412
19.11Class的取值函数(getter)和存值函数(setter)412
19.12Class的Generator方法413
19.13Class的静态方法414
19.14Class的静态属性和实例属性415
19.15new.target属性418
第20章Class的继承421
20.1简介421
20.2Object.getPrototypeOf()423
20.3super关键字423
20.4类的prototype属性和__proto__属性429
20.4.1extends的继承目标430
20.4.2实例的__proto__属性432
20.5原生构造函数的继承432
20.6Mixin模式的实现436
第21章修饰器439
21.1类的修饰439
21.2方法的修饰442
21.3为什么修饰器不能用于函数444
21.4core-decorators.js446
21.5使用修饰器实现自动发布事件449
21.6Mixin450
21.7Trait453
21.8Babel转码器的支持456
第22章Module的语法457
22.1概述457
22.2严格模式458
22.3export命令459
22.4import命令462
22.5模块的整体加载464
22.6exportdefault命令465
22.7export与import的复合写法468
22.8模块的继承469
22.9跨模块常量470
22.10import()471
22.10.1简介471
22.10.2适用场合472
22.10.3注意点473
第23章Module的加载实现475
23.1浏览器加载475
23.1.1传统方法475
23.1.2加载规则476
23.2ES6模块与CommonJS模块的差异477
23.3Node加载481
23.4循环加载485
23.5ES6模块的转码492
第24章编程风格495
24.1块级作用域495
24.2字符串497
24.3解构赋值497
24.4对象498
24.5数组500
24.6函数501
24.7Map结构503
24.8Class503
24.9模块504
24.10ESLint的使用506
第25章读懂ECMAScript规格509
25.1概述509
25.2相等运算符510
25.3数组的空位511
25.4数组的map方法513
第26章ArrayBuffer517
26.1ArrayBuffer对象518
26.2TypedArray视图521
26.3复合视图534
26.4DataView视图535
26.5二进制数组的应用537
26.6SharedArrayBuffer541
26.7Atomics对象543

前言/序言

第3版前言

4年前,当我开始写这《ES6标准入门(第3版)》的时候,ECMAScript5.1版刚刚开始普及,最流行的框架还是jQuery。ES6看上去就像一个遥远的蓝图,无人知道何时会实现。

仅仅4年,ES6已经经历了ES2015、ES2016、ES2017这3个版本的迭代,各种实现的支持度已经超过90%,不仅可以实现网页的编写,还可以实现服务器脚本、手机App和桌面应用的编写。程序员们完全接受了这个标准,甚至大量使用尚未标准化的新语法。JavaScript语言就像一列高铁,以令人“眩晕”的速度向前冲刺。

互联网行业的蓬勃兴旺造就了ES6的成功,也使得这本教程不断更新,越写越厚。第2版问世18个月之后,不得不推出第3版。

第3版新增了超过30%的内容,完全覆盖了ES2017标准(第2版只做到覆盖ES2015标准),并且对所有章节都进行了修订,文字表达更准确易懂,示例更丰富。对读者来说,这个版本更容易学习,更有参考价值。

这4年来,我对ES6的理解和所有的学习笔记,都浓缩在这本教程里面。那些我自己感到最困难的地方,书中都做出了详细讲解,给出了细致的示例,我相信这也是其他国内学习者所需要的。

这本教程当然也包含了些许局限,以及细致检查之后仍然疏漏的各种错误。一旦发现,我会第一时间更正。读者可以到官方仓库github.com/ruanyf/es6tutorial中查看勘误。

我在微博上曾经说过一段话,就把它放在这里作为结束吧。

“我水平其实不高,只是好奇心重,从没想到这么多人会关注。希望不要让大家失望,未来做一块垫脚石,为需要的朋友提供帮助,为技术的推广和发展做出力所能及的贡献。”

阮一峰

2017年8月1日,写于杭州

第1版前言

2012年年底,我开始动手做一个开源项目《JavaScript标准参考教程》(github.com/ruanyf/jstutorial)。原来的设想是将自己的学习笔记整理成一《ES6标准入门(第3版)》,哪里料到,这个项目不断膨胀,最后变成了ECMAScript5及其外围API的全面解读和参考手册,写了一年多还没写完。

那个项目的最后一章就是ECMAScript6的语法简介。那一章也是越写越长,最后我不得不决定,把它独立出来,作为一个新项目,也就是您现在看到的这《ES6标准入门(第3版)》。

JavaScript已经是互联网开发的第一大语言,而且正在变成一种全领域的语言。著名程序员JeffAtwood甚至提出了一条“Atwood定律”:“所有可以用JavaScript编写的程序,最终都会出现JavaScript的版本。”(AnyapplicationthatcanbewritteninJavaScriptwilleventuallybewritteninJavaScript.)

ECMAScript正是JavaScript的国际标准,这就决定了该标准的重要性。而ECMAScript6是ECMAScript历史上最大的一次版本升级,在语言的各个方面都有极大的变化,即使是熟练的JavaScript程序员,也需要重新学习。由于ES6的设计目标是企业级开发和大型项目,所以可以预料,除了互联网开发者,将来还会有大量应用程序开发者(甚至操作系统开发者)成为ES6的学习者。

我写作这《ES6标准入门(第3版)》的目标,就是想为上面这些学习者提供一本篇幅较短、简明易懂、符合中文表达习惯的ES6教程。它由浅入深、循序渐进,既有重要概念的讲解,又有API接口的罗列,便于日后当作参考手册查阅,还提供大量示例代码,让读者不仅一看就懂,还能举一反三,直接复制用于实际项目之中。

需要声明的是,为了突出重点,《ES6标准入门(第3版)》只涉及ES6与ES5的不同之处,不对JavaScript已有的语法进行全面讲解,毕竟市面上这样的教程已经有很多了。因此,《ES6标准入门(第3版)》不是JavaScript入门教材,不适合初学者。阅读《ES6标准入门(第3版)》之前,需要对JavaScript的基本语法有所了解。

我本人也是一个ES6的学习者,不敢说自己有多高的水平,只是较早地接触了这个主题,持续地读了许多资料,追踪标准的进展,做了详细的笔记而已。虽然我尽了最大努力,并且原稿在GitHub上公开后已经得到了大量的勘误,但是《ES6标准入门(第3版)》的不尽如人意之处恐怕还有不少。

欢迎大家访问《ES6标准入门(第3版)》的项目主页(github.com/ruanyf/es6tutorial),提出意见,提交pullrequest。这些都会包括在《ES6标准入门(第3版)》的下一个版本中。

阮一峰

2014年6月4日,写于上海


其他推荐