JavaScript语言精髓与编程实践pdf下载pdf下载

JavaScript语言精髓与编程实践百度网盘pdf下载

作者:
简介:本篇主要提供JavaScript语言精髓与编程实践pdf下载
出版社:电子工业出版社
出版时间:2020-06
pdf下载价格:0.00¥

免费下载


书籍下载


内容介绍

产品特色

编辑推荐

适读人群 :JAVASCRIPT语言精髓与编程实践》适合于有编程经验的、想学习和掌握JavaScript的语言实现与扩展知识的开发者。

√ 绿皮书正式版:经过前两个版本的积累和历经三年的全面重写,这本书终于达成技术剖析和用户体验的完美契合
√ 广深铸就宏篇:论深,本书深究JS之所以然,举世无可出其右;论广,本书遍历语义之细部,看罢再无机理之惑
√ 超语言之思想:万法归宗异曲同工,剥去JS外壳,本书居高处辨析语言奥义的技术大局观,适用于所有编程语言
√ 修炼重在重学:混合App|Node服务端|FaaS云原生|前端智能化时代,回归本质重修这门基础课才能走得更远更快

内容简介

JavaScript 是一门包含多种语言特性的混合范型语言,在面向对象和函数式语言特性方面表现尤为突出,且在 ES6 之后所添加的并行语言特性也极为出色。《JavaScript语言精髓与编程实践(第3版)》基于 ES6,并涵盖 ES2019 规范,全面讲述 JavaScript 在五个方面的语言特性,以及将这些特性融会如一的方法。本书不但完整解析了 JavaScript 语言,还逐一剖析了相关特性在多个开源项目中的编程实践与应用,是难得的语言学习参考书。

本书作者在前端开发领域经验丰富、深耕不辍,一书三版,历经十余年。书中对 JavaScript 语言的理解与展望,尤其适合期望精通这门语言的中高级程序员和语言实践者阅读。


作者简介

周爱民( Aimingoo )

南潮( ruff.io )架构师、知名JavaScript专家。从1996年开始涉足商业软件开发,在软件开发、软件工程、团队建设以及部门管理方面经验丰富,曾任zfb(中国)公司业务架构师、盛大网络平台架构师、豌豆荚架构师等职。著有《Delphi源代码分析》《大道至简》《大道至易》《程序原本》《动态函数式语言精髓》《 我的架构思想》《 JavaScript语言精髓与编程实践》等图书。


精彩书评

第一次接触爱民这本书的第1版是在2008年下半年,那时候学习前端时间不长,对很多知识点理解得也不深入,阅读这本书时带给我很多欣喜,同时对我的思维方式影响也很大。看完书后,明显感觉自己对JavaScript的理解有了质的飞跃,对我前期的学习帮助非常大,建议希望提升自己JavaScript水平的小伙伴阅读这本书(结合ECMAScript标准规范阅读,效果会更好)。
李成银( welefen),Think JS框架作者

目录

第 1 章 二十年来的 JavaScript 1

1.1 网页中的代码1

1.1.1 新鲜的玩意儿 1

1.1.2 写在网页中的第一段代码 2

1.1.3 最初的价值 3

1.2 用 JavaScript 来写浏览器上的应用5

1.2.2 Flash 的一席之地 7

1.2.3 RWC 与 RIA 之争 8

1.3 没有框架与库的语言能怎样发展呢 10

1.3.1 做一个框架10

1.3.2 重写框架的语言层 .13

1.3.3 富浏览器端开发(RWC)与 AJAX14

1.4 语言的进化16

1.4.1 Qomo 的重生16

1.4.2 QoBean 是对语言的重新组织 .17

1.4.3 JavaScript 作为一门语言的进化18

1.5 大型系统开发20

1.5.1 框架与架构是不同的 .20

1.5.2 大型系统与分布式的环境 21

1.5.3 划时代的 ES6.23

1.6 为 JavaScript 正名 24

1.6.1 JavaScript .25

1.6.1.1 Core JavaScript26

1.6.1.2 SpiderMonkey JavaScript 27

1.6.1.3 JScript .27

1.6.2 ECMAScript 28

1.7 JavaScript 的应用环境29

1.7.1 宿主环境 30

1.7.2 外壳程序

第 2 章 JavaScript 的语法 36
2.1 语法综述 36
2.1.1 标识符所绑定的语义.37
2.1.2 识别语法错误与运行错误38
2.2 JavaScript 的语法:声明 .40
2.2.1 变量的数据类型.40
第 2 章 JavaScript 的语法 . 36
2.1 语法综述36
2.1.1 标识符所绑定的语义 37
2.1.2 识别语法错误与运行错误 .38
2.2 JavaScript 的语法:声明40

2.2.2 变量声明 45

2.2.4 其他声明 53

2.2.4.1 常量声明 ..53

2.2.4.2 符号声明 ..54

2.2.4.3 函数声明 ..55

2.3 JavaScript 的语法:表达式运算 ......56

2.3.1 一般表达式运算 .....59

2.3.2 比较运算 61

2.3.3 赋值运算 67

2.3.4 函数相关的表达式 .6

2.3.5 特殊作用的运算符 .72

2.3.6 运算优先级 ...76

2.4 JavaScript 的语法:语句 ....78

2.4.1 表达式语句 ...80

2.4.2 变量声明语句 ..86

2.4.3 分支语句 87

2.4.4 循环语句 89

2.4.5 流程控制:一般子句 ....91

2.4.6 流程控制:异常 .....96

2.5 JavaScript 的语法:模块 ....97

2.5.1 模块的声明与加载 .98

2.5.2 名字空间的特殊性 ......101

2.6 严格模式下的语法限制 ...105

2.6.1 语法限制 .....106

2.6.2 执行限制 .....108

2.6.3 严格模式的范围 ... 110

2.7 运算符的二义性 ..... 112

2.7.1 加号“+”的二义性 .... 114

2.7.2 括号“( )”的二义性 ... 114

2.7.3 冒号“:”与标签的二义性 116

2.7.4 大括号“{ }”的二义性 ..... 117

2.7.5 逗号“,”的二义性 .....122

2.7.6 方括号“[ ]”的二义性 ......123

2.7.7 语法设计中对二义性的处理.....127

第 3 章 JavaScript 的面向对象语言特性 . 130

3.1 面向对象编程的语法概要 ......130

3.1.1 对象声明与实例创建 ..132

3.1.2 使用类继承体系 ...141

3.1.3 对象成员 .....147

3.1.4 使用对象自身 157

3.1.5 符号 ......158

3.2 JavaScript 的原型继承 ......161

3.2.1 空(null)与空白对象(empty) ......161

3.2.2 原型链的维护 171

3.2.3 原型继承的实质 ...175

3.3 JavaScript 的类继承 179

3.3.1 类是静态的声明 ...179

3.3.2 super 是全新的语法元素 ....181

3.3.3 类是用构造器(函数)来实现的 189

3.3.4 父类的默认值与 null 值 .....192

3.4 JavaScript 的对象系统 ......196

3.4.1 封装与多态 .196

3.4.2 属性 ......201

3.4.3 构造对象系统的方法 ..206

3.4.4 内置的对象系统 ...214

3.4.5 特殊效果的继承 ...226

3.5 可定制的对象属性 .229

3.5.1 属性描述符 .230

3.5.2 定制对象属性 233

3.5.3 属性表的状态 239

3.6 运行期侵入与元编程系统 ......242

3.6.1 关于运行期侵入 ...243

3.6.2 类类型与元类继承 ......257

3.6.3 元编程模型 .266

第 4 章 JavaScript 语言的结构化 ..... 269

4.1 概述 ....269

4.1。1 命令式语言 .270

4.1.2 面向对象语言 275

4.1.3 再论语言的分类 ...281

4.1.4 JavaScript 的语源 ..283

4.2 基本的组织元素 .....284

4.2.1 标识符 ..285

4.2.2 表达式 ..286

4.2.3 语句 ......288

4.2.4 模块 ......289

4.2.5 组织的原则 .290

4.3 声明 ....294

4.3.1 声明名字 .....295

4.3.2 确定性 ..296

4.3.3 顶层声明 .....297

4.4 语句与代码分块 .....300

4.4.1 块 ...301

4.4.2 块与语句的语法结构 ..303

4.4.3 块与声明语句 309

4.4.4 块与语句的值 312

4.5 组织形式分块的方法 318

4.5.1 词法作用域 .319

4.5.3 词法作用域之间的相关性 .336

4.5.4 执行流程变更的内涵 ..337

4.6 层次结构程序设计 .340

4.6.1 属性的可见性 341

4.6.2 多态的逻辑 .343

4.6.3 私有作用域的提出 ......347

4.7 历史遗产:变量作用域 ...349

4.7.1 变量作用域 .350

4.7.2 变量的特殊性与变量作用域的关系 353

4.8 私有属性与私有字段的纷争356

4.8.1 私有属性的提出 357

4.8.2 从私有属性到私有成员 361

4.8.3 “类字段”提案的实现概要364

4.8.4 “私有属性”提案的设计与提议 368

4.8.5 “私有属性”提案的实现 .373

第 5 章 JavaScript 的函数式语言特性 ..... 381

5.1 概述 ....381

5.1.1 从代码风格说起 ...382

5.1.2 为什么常见的语言不赞同连续求值 ...383

5.1.3 函数式语言的渊源 ......384

5.2 从运算式语言到函数式语言...386

5.2.1 JavaScript 中的几种连续运算 ...386

5.2.2 如何消灭语句 391

5.2.3 运算式语言 .394

5.2.4 重新认识函数 397

5.2.5 函数式语言 .401

5.3 JavaScript 中的函数 405

5.3.1 参数 ......405

5.3.2 函数 ......418

5.3.3 函数的数据性质 ...431

5.3.4 函数与逻辑结构 ...439

5.4 函数的行为 ......443

5.4.1 构造 ......444

5.4.2 调用 ......448

5.4.3 方法调用 .....455

5.4.4 迭代 ......461

5.4.5 生成器中的迭代 ...466

5.5 闭包 ....475

5.5.1 闭包与函数实例 ...476

5.5.2 闭包的使用 .481

5.5.3 与闭包类似的实例化环境 .487

5.5.4 与闭包相关的一些特性 .....496

第 6 章 JavaScript 的动态语言特性 . 506

6.1 概述 ....506

6.1.1 动态数据类型的起源 ..507

6.1.2 动态执行系统 507

6.1.3 脚本系统的起源 ...509

6.1.4 脚本只是表现形式 ......510

6.2 动态类型:对象与值类型之间的转换 .512

6.2.1 包装类:面向对象的妥协 .512

6.2.2 从对象到值 .520

6.2.3 显式的转换 .529

6.3 动态类型:值类型的转换 ......532

6.3.1 值运算:类型转换的基础 .532

6.3.2 值类型之间的转换 ......535

6.3.3 值类型之间的显式转换 .....540

6.4 动态类型:对象与数组的动态特性 .....545

6.4.1 关联数组与索引数组 ..545

6.4.2 索引数组作为对象的问题 .546

6.4.3 类数组对象:对象作为索引数组的应用 ..552

6.4.4 其他 ......554

6.5 重写 ....555

6.5.1 标识符的重写及其限制 .....555

6.5.2 原型重写 .....567

6.5.3 构造器重写 .569

6.5.4 对象成员的重写 ...573

6.5.5 引擎对重写的限制 ......578

6.6 动态执行 ...582

6.6.1 eval()作为函数名的特殊性 582

6.6.2 eval()在不同上下文环境中的效果 .....584

6.6.3 Eval 环境的独特性 ......586

6.6.4 动态执行过程中的语句、表达式与值 ......593

6.6.5 序列化与反序列化 ......595

6.6.6 eval 对作用域的影响 ...600

6.6.7 其他的动态执行逻辑 ..601

6.7 动方法调用(call、apply 与 bind) .605

6.8 通用执行环境的实现 615

6.8.1 通用 DSL 的模型 ..616

6.8.2 实现 ECMAScript 引擎 ......624

6.8.3 与 DSL 的概念整合 .....635

第 7 章 JavaScript 的并行语言特性 . 638

7.1 概述 ......638

7.1.1 并行计算的思想 ...638

7.1.2 并行程序设计的历史 ..642

7.1.3 并行语言特性在 JavaScript 中的历史 645

7.2 Promise 的核心机制 ..647

7.2.1 Promise 的核心过程 ....647

7.2.2 Promise 类与对象的基本应用 ..654

7.2.3 Promise 的子类 .....663

7.2.4 执行逻辑 .....666

7.2.4.1 任务队列 666

7.2.4.2 执行栈 ....667

7.3 与其他语言特性的交集 ...668

7.3.1 与函数式特性的交集:异步的函数 ...669

7.3.2 与动态特性的交集 ......677

7.3.3 对结构化特性带来的冲击 .683

7.3.3.4 异步方法与存取器 .....687

7.4 JavaScript 中对并发的支持 .....690

7.4.1 Agent、Agent Cluster 及其工作机制 ..691

7.4.2 SharedArrayBuffer 698

7.4.3 Atomics.701

7.5 在分布式网络环境中的并行执行 ..706

7.5.2 构建一个集群环境 ......709

7.5.3 使用 PEDT 执行行任务 .713

7.5.4 可参考的意义 718

附录 A 术语表 ... 719

附录 B 参考书目 ...... 723

附录 C 图表索引 ...... 725

附录 D 本书各版次主要修改 .. 731


前言/序言

推荐序 1
一本不是所有人都需要的好书
这个有点绕口的标题,是从豆瓣上本书第 1 版的一个书评标题照录而来的。豆瓣上排名前列的评论还有“这是一本硬书”“国内技术原创书中稀有的‘异数’”等。实际上,我觉得不仅是国内,算上在市面上能看到的所有 JavaScript 相关的书,本书都绝对堪称“硬书”“异数”。
传统上,许多大部头的 JavaScript 相关的图书,会有大量篇幅介绍 DOM 相关的 API 和如何结合语言与平台 API 进行 Web 前端编程,这些年也可能换成是 Node.js 的 API 和服务器端编程。从入门或进阶来说,这样的编排都是合适的,因为结合特定平台和领域的具体编程实践可以更快速地建立学习的正向反馈。专注 JavaScript 语言本身的书也不是没有,ES6 时代到来之后,颇有几本书全面细致地介绍了 JavaScript 语言的新特性。甚至有很有名的书,会一直讲到不为多数人所知的语言细节,受到中高级开发者的追捧。不过这些书还都是用来“学习”语言的书。
爱民的这本书,却不是一本“学习”用的书,而是一本“阐释”用的书。不要说 JavaScript 初学者,就算你有三五年甚至十年的 JavaScript 开发经验,读起这本书可能也不易。因为绝大部分开发者不习惯这样思考问题。比方说,这本书大的章节是按照结构化、面向对象、函数式、动态化等编程范式来展开讨论的,最新版中还加入了“并行计算”。
有些读者或许也看过一些谈编程范式的书,甚至专门谈在 JavaScript 语言中使用某一种编程范式的书(比如近年来随着某框架而在 JavaScript 圈逐渐火起来的函数式编程),但这些书还都是引领你“学习”一个范式,教你“应用”一个范式的书。爱民这本书的出发点与其他书不同,并不是为了学习、应用“范式”,而是为了分析“编程语言”,取之为线索。为此,需要系统性地逐一论述多种主要范式,然后将 JavaScript 语言的要素分解并归纳入不同范式下进行讨论。需要注意的是,JavaScript 语言与每种范式代表性的经典编程语言都有很大的不同。所以在这个过程中,读者也可以注意体悟多种范式是以怎样一种方式不完美却可用地并存于 JavaScript 这门语言之中的。
在每章的开始,先有十数页的概述来论述范式和其背后的思想源流,故这一部分几乎总是要以跳出 JavaScript 这单一语言的视角来论述的。这些概述也绝不是简单地从其他书或资料中拿一些内容拼凑而成的,而是爱民以自己数十年编程和架构的心得理解精炼而成的。光这些概述,在本书第 1 版出版时的技术图书市场上前所未见,到今日 JavaScript 的相关图书汗牛充栋,恐怕也仍然独此一家。
不过,这也带来一个问题,就是对于绝大多数读者来说,概述可能反而比后续章节更难读,初读时一知半解。
这次爱民要出第 3 版,寄赠我一些样稿,我读到第 4 章概述中论及“结构化的疑难”是“抽象层次过低”,而“面向对象”范式正是对此的应答时,颇有茅塞顿开之感。但后来重新翻阅 12 年前爱民赠我的本书第 1 版,才发现已包含了这段论述。可见当年我恐怕也是囫囵吞枣,虽读之也并不能领会消化。
然而即使我现在提到了这个段落,读者可能特意去认真阅读该段落,记住了、理解了,也不见得能产生直接的“用处”。打个不一定恰当的比喻,金庸的《射雕英雄传》中周伯通讲《九阴真经》:“这上卷经文中所载,都是道家修炼内功的大道,以及拳经剑理,并非克敌制胜的真实功夫,若未学到下卷中的实用法门,徒知诀窍要旨,却是一无用处。”
市面上大部分技术图书,都是讲“实用法门”的,偶尔讲一点“拳经剑理”。爱民写这本书的终极目标其实是传授“内功大道”,为此拿了一门最流行的武功(语言)来拆解剖析,总结出其独特的“拳经剑理”,以印证“大道”。在这个阐释的过程中,“实用法门”讲的不多,即使讲了一些,也意不在此。事实上,很多人只是想要“实用法门”的书,最好还是速成的。那就最好不要选本书了。这种需求也不好说错。或许先讲“实用法门”,再讲“拳经剑理”乃至“大道”,才是符合普通人的认知规律的。
另一方面,即使一个人也有意于“拳经剑理”乃至“大道”,如果市面上全是讲“实用法门”的书,他一直以来熟悉的只有这个套路,就会对其他模式不太适应。比如说,对一个语言特性的解说和评论,绝大部分图书的讲法主要基于“实用”,也就是,有什么用,怎么用,用起来顺手不顺手。但爱民这本书的视角就很不一样,主要是基于“大道”和“拳经剑理”的内在逻辑进行推演。
需要理解的是,这两个方向可能互相印证,也可能产生矛盾。编程语言和一切复杂的人造事物一样,是不完美的。
这也会延伸到语言设计上。作为程序员,虽然看到新语言特性的介绍通常还都是从“实用”角度讲解(宣传)的,但在设计阶段,其实要接受各个维度、不同层面的需求和约束。语言特性要平衡多种不同因素,平衡不了就要做取舍。但这个取舍到底是不是合适,就见仁见智了。
爱民在这次新版的第 4 章中花了不少篇幅讨论目前 stage 3 的类字段(class fields)提案和他设计的替代性方案。这个提案比表面上看起来要复杂得多,无论是在委员会还是在社区里,不同的人的看法会非常不同,而且这种分歧贯穿了“大道”“拳经剑理”“实用法门”各个层面。需要注意,即使持同样立场的人,比方说同样反对现有提案,其背后的原因也可能截然不同,对解决路径的判断也会截然不同。TC39 是基于一致同意的方式推进工作的。对于接受现有提案的人来说,即使其认知不同,但至少表面上是达成一致的。而对不同意现有提案的人,各有各的不同意,因而也无法达成一致。表现出来的结果,就是爱民在书中所说:“类字段提案提供了一个极具争议的私有字段访问语法,并成功地做对了唯一一件事情,让社区把全部的争议焦点放在了这个语法上”。这也是类字段提案的悲剧性之所在。
我认为,讨论这个话题的价值,不在于给出一个答案(毕竟 TC39 都给不出令人满意的答案),而是这个思考过程。在这个过程中,我们需要同时考虑“大道”(面向对象范式)、“拳经剑理”(JavaScript 现有的语法和语义约定和约束,与后续提案的关系和协调性等)、“实用法门”(使用方式、如何满足各种需求、代码风格、性能……)等不同的层面。这是一个极好的思维训练,在这个过程中,无论你得到怎样的结论,都会对 JavaScript 语言有更深
层次的认知和把握。而这样的内容,也只能存在于“阐释”之书中。
然后说说对“阐释”可能存在的疑问。那就是多种不同的甚至矛盾的“阐释”是否可以共存,有没有一种解释是最正确的,或者权威的。
举一个小例子, typeof null 为什么返回 "object" ?从历史事实来说,根据Brendan Eich 自己的说法,这是无心之失。但爱民的意见,这也可以理解为 null 实为对象类型的特殊值。6年前我在知乎上对这种“阐释”做了较为详细的解说。按照一般认知,Brendan Eich 自己的说法当然是最正确和权威的。然而有意思的是,前不久,在 Allen Wirfs-Brock 和 Brendan Eich 合作撰写并提交给 HOPL 会议的论文 JavaScript : The First 20 Years 中写道:
……令人困惑的是,typeof null 会返回字符串值"object"而不是"null"。其实也可以说这与Java 保持了一致,因为 Java 中的所有值都是对象,而 null 本质上是表达“没有对象”的对象……根据 Brendan Eich 的回忆, typeof null 的值是原始 Mocha 实现中“抽象泄露”的结果。 null 的运行时值使用了与对象值相同的内部标记值进行编码,因此 typeof 运算符的实现就直接返回了"object"。
——引自 doodlewind 的中文译本,原文在预印本第 12 页
这篇权威论文同时列出了这两种解释。所以爱民很多年前的阐释也算被“官宣”了。有人可能要打破砂锅问到底,到底哪一种才是“正确”的呢?其实我认为都是正确的。
Brendan Eich 的回忆可能是历史真相,但当事人的回忆不一定是真相的全部。我们可以追问,为什么当初在实现的时候,对象和 null 共享了相同的标记值呢?一种解释是,可能是当年有意识“根据 Java 的 null 值表示‘没有对象’,来对 JavaScript 中的 null 值进行建模”的副产品,另一种解释是编程中无意产生的结果。即使是后一种,如果考虑引擎是如何实现的,就会发现对象引用的内部表达肯定是一个内存地址,那么很自然就会以全0的地址代表 null 。
那么可以说,导致这种“抽象泄露”本身的源头是高层模型到具体实现的自然映射,偶然性中蕴含了必然性。另外,我们也可以追问,为什么当初标准化的时候,没有对 typeof null 的结果提出异议呢?不太可能委员会中的所有成员都没有发现,所以一个合理猜想是,发现这个问题的人也采用了类似爱民的阐释对这个行为进行了“合理化”。
其实在日常生活中,有大量这种既是“机缘巧合”又“冥冥中自有定数”的事例,在技术领域其实也一样。
这当然不是说,任意一种“阐释”都是正确的,“阐释”本身得自洽,然后有足够的解释效力,具有普适性,不会引发反例,引入一种“阐释”的成本不应该大于收益,最后还要经得起“奥卡姆剃刀”原则的考验。要做到这些是非常困难的,有时候是难以判断的。包括本书对 JavaScript 语言的各种“阐释”,肯定不是所有人都认同的,包括我自己,对其中某些部分也会有不同意见。但是程序员从“码农”成长起来,可以进行更大范围、更高层次的设
计,乃至以成为像爱民那样的“架构师”为职业目标,这就需要提升对各种不同“阐释”的理解判断及融会贯通的能力,并逐步形成自己对技术进行“阐释”的能力。从这点来说,这本“硬书”在那么多 JavaScript 书中是独具价值的。
当然,这样的“阐释”之书,啃起来不容易。豆瓣上有一些吐槽,这些评论绝不是恶意的,实际上这些评论者总体上都是赞许本书的。我自己当年读本书第 1 版时也有同感。今天我读样稿时感觉倒是好了不少,可能是爱民做了一些优化,但估计更多是随着年岁渐长,我本身的技术水平提升了,对“阐释”之书的阅读能力也提升了。尤其这一年以来,亲身参与在 TC39 之中,感受到对JavaScript 的“阐释”即使在委员会里本身也是具有多重性和不确定性的,这产生了很多问题,但也是活力的一部分。所以对不同“阐释”的包容和理解,乃是必需的。
不过即使考虑阅读能力有所提升,本书的阅读体验和“流畅”“阅读快感”也是不搭界的。这是读者在读本书前需要有的心理准备。
最后总结,“阐释”之书定然“不是所有人都需要的”,但我个人希望这样的书可以多来几本。
——贺师俊 2020 年 4 月