书籍详情

JavaScript核心原理:规范、逻辑与设计

JavaScript核心原理:规范、逻辑与设计

作者:周爱民

出版社:人民邮电出版社

出版时间:2023-07-01

ISBN:9787115608925

定价:¥99.80

购买这本书可以去
内容简介
  本书是一本JavaScript精进指南,全面剖析JavaScript的核心技术。全书共分为6篇,第一篇讲解JavaScript的基础概念,第二篇讲解JavaScript的运行过程,第三篇讲解JavaScript面向对象编程体系中最核心的设计,第四篇讲解JavaScript作为动态语言的主要特性,第五篇讲解JavaScript作为并行语言的主要持性,第六篇讲解ECMAScript 2019之后的新增特性,并对ECMAScript 2022之后将添加的特性进行解析。 每章用一行代码引出,所讲内容包括该行代码的特殊性、所涉问题的领域、逐步的解析、相似或同类的问题、潜在的应用、不为人知的历史、标准规范对此代码的态度、业界的看法与争议等。 本书适合有一定编程基础的JavaScript开发人员与深度爱好者阅读,帮助读者深入理解JavaScript核心原理,实现从粗通到精通的进阶。
作者简介
  周爱民,国内软件开发界资深架构师、软件工程师。有20余年的软件开发与架构、项目管理、团队建设的经验,曾任盛大网络平台架构师、支付业务架构师、豌豆英架构师和上海南潮架构师等职。从1998年开始了解并应用JavaScript,著有前端“绿皮书”《JavaScript语言精髓与编程实践》,曾发布Qomo、 QoBean及分布式架构框架N4C等开源项目。已出版的其他作品有《大道至简》 《大道至易》和《Delphi源代码分析》。
目录
第 一篇 从零开始:重新认识JavaScript语言的基础概念
第 1章 生存周期:JavaScript变量与引用的销毁 2
1.1 习惯中用“引用”来区别数据类型的操作方式 3
1.1.1 删除运算到底在试图销毁什么 4
1.1.2 表达式的结果是什么 4
1.2 深入理解“引用(规范类型)” 5
1.3 引用在引擎内部的主要行为 6
1.4 从引用的发现到销毁 6
1.5 小结 7
第 2章 赋值:赋值过程中出现变量泄露的原因 9
2.1 从变量声明到赋值绑定的全程解析 10
2.1.1 赋值在语言设计中称为绑定 11
2.1.2 用赋值语法实现绑定导致的问题 12
2.2 变量泄露:向一个不存在的变量赋值 12
2.3 在连续赋值过程中发生的行为细节 14
2.4 在应用中使用“赋值语句魔法”的技巧 15
2.5 小结 16
第3章 表达式:对运算过程的观察与分析 17
3.1 在运算过程中丢失的数据的难解之谜 18
3.1.1 深度解析声明语句与赋值表达式的语义差别 18
3.1.2 来自《JavaScript权威指南》的解释 19
3.2 表达式连续运算过程中的变量、值与引用 20
3.3 用代码重现引用覆盖的现场 21
3.4 技术的取巧之处 22
3.5 小结 23
第4章 名字与导出:“有名字”是构建逻辑的基础 24
4.1 能导出的只有名字和值 25
4.1.1 代码就是文本 25
4.1.2 详解export的语法与语义 25
4.2 export导出名字的具体逻辑 27
4.2.1 导出:同化名字与值的处理逻辑 27
4.2.2 绑定:通过执行顶层代码实现的装配过程 28
4.2.3 问题:函数表达式执行中不绑定名字 28
4.3 匿名函数定义及其名字处理 29
4.4 有关导出语句的一些补充 30
4.5 小结 31
第5章 作用域:循环计算成本高昂的原因 32
5.1 代码分块与块级作用域 33
5.2 循环语句中的块 34
5.2.1 特例 35
5.2.2 特例中的特例 35
5.3 第二个作用域的必要性 36
5.4 for循环在运行时需要更多作用域 37
5.5 小结 38
第二篇 从表达式到执行引擎:运行代码的核心机制
第6章 执行环境的秘密:语句的运行与完成的视角 40
6.1 用中断代替跳转 41
6.1.1 跳转到语句结束的位置 41
6.1.2 跳转到标签约定的位置 42
6.2 执行现场的回收 43
6.3 语句执行的意义 44
6.4 中断语句的特殊性 45
6.4.1 最小化的break语句 46
6.4.2 返回empty的语句 46
6.5 小结 46
第7章 深入探索JavaScript中的特殊执行体 47
7.1 抽象确定逻辑的执行体 48
7.2 几种特殊的可执行结构 48
7.2.1 参数表 48
7.2.2 扩展风格的参数表 49
7.2.3 赋值模式 50
7.3 模板字面量 52
7.4 小结 53
第8章 闭包、函数与函数式编程语言的关系 54
8.1 函数的一体两面 55
8.1.1 在运行期一个实例有多个闭包 55
8.1.2 闭包用于承载两个语义组件 56
8.2 简单参数类型 57
8.2.1 传入参数的处理 57
8.2.2 意外 58
8.2.3 未初始化绑定 58
8.3 最小化的函数式编程语言示例 59
8.4 小结 60
第9章 迭代过程及其出错处理机制 61
9.1 递归与迭代 62
9.1.1 迭代对执行过程的重造和使用 63
9.1.2 展开语法 63
9.2 JavaScript中如何实现迭代处理 64
9.2.1 内部迭代过程 64
9.2.2 不可思议的异常处理逻辑 65
9.3 在迭代中处理异常的关键:谁是使用者 66
9.4 小结 68
第 10章 从迭代向生成器函数演进的过程 69
10.1 将迭代过程代表的循环逻辑展开 70
10.2 用生成器函数对循环逻辑进行二次重构 71
10.3 由next()方法负责执行引擎的唤起 73
10.4 为next()方法的传入参数赋予新的意义 73
10.5 小结 74
第 11章 ECMAScript规范起步 75
11.1 第三行:返回结果 76
11.2 第二行:取引用的值 77
11.2.1 语句的执行者 77
11.2.2 执行期值的覆盖与读取 78
11.2.3 取引用值的具体方法 79
11.3 第 一行:从执行到取结果的基础模式 80
11.4 在ECMAScript中如何理解值1 80
11.5 小结 81
第三篇 从原型到类:向应用编程语言的进化
第 12章 详解属性及其性质 84
12.1 JavaScript 1.0~1.3中的对象 85
12.1.1 面向对象的基础设计与实现 85
12.1.2 属性存取及其可见性问题 86
12.2 自有属性与从原型中继承来的属性 87
12.3 字面量、标识符与属性 88
12.4 属性存取的不确定性 88
12.5 小结 89
第 13章 从构造器到类:创建对象的方法 90
13.1 JavaScript支持继承的历史 91
13.1.1 基于对象的JavaScript 91
13.1.2 类与构造器 91
13.1.3 ES6之后的类 92
13.1.4 总结 93
13.2 两种创建对象this的顺序 94
13.3 改变对象创建的结果 95
13.4 小结 96
第 14章 从无到有:访问父类的能力 97
14.1 面向对象早期设计中的概念抽象 98
14.2 为什么要有super 98
14.3 super指向什么 99
14.4 调用父类方法super.xxx() 100
14.4.1 super.xxx()中的this值 100
14.4.2 super()中的父类构造方法 101
14.4.3 构造方法在设计时面临的选择 102
14.5 访问父类属性super.xxx 102
14.6 小结 103
第 15章 实现用户自定义的构建过程 105
15.1 自定义构建过程的必要性 106
15.1.1 关于隐式的构造方法 106
15.1.2 非派生类不用调用super() 107
15.2 定制的构造方法 108
15.3 定制构造器能返回任意对象 109
15.4 小结 109
第 16章 数据结构视角下的对象本质 111
16.1 对象的前世今生 112
16.2 两种数据结构 113
16.3 结构的反面:解构 114
16.4 对象将两种数据结构合而为一 115
16.5 小结 117
第 17章 原子层级上的对象与行为 118
17.1 null值 119
17.2 Null类型 120
17.3 null是所有原子对象的父类实例 121
17.4 从继承性的角度观察原子对象 122
17.4.1 派生自原子的类 122
17.4.2 一般函数/构造器 123
17.5 原子行为 124
17.6 小结 124
第四篇 从粗通到精通的进阶之路:唯一不变的是变化本身
第 18章 原始值:类型系统运算的终极目标 126
18.1 类型系统的简化 127
18.1.1 从值到对象的类型转换 127
18.1.2 对象可以转换成哪些值 127
18.1.3 值与值之间的转换 129
18.2 问题:将数组和对象相加会发生什么 130
18.3 分析:隐式转换中的意图推断和转换过程 131
18.3.1 返回值本身 131
18.3.2 返回内部槽中的原始值 132
18.3.3 作为原始值处理 132
18.3.4 使用传统的类型转换逻辑 133
18.4 解题 133
18.4.1 从对象到原始值的转换 133
18.4.2 加号运算符的特殊性 134
18.4.3 字符串在加号运算符中的优先权 134
18.4.4 预期情况与非预期情况下的处理 135
18.5 Date特例的进一步分析 136
18.6 小结 137
第 19章 JavaScript实现动态执行时的基础设施 138
19.1 eval执行对传入参数的理解 139
19.2 eval执行对环境的要求 139
19.2.1 环境 140
19.2.2 执行上下文 140
19.2.3 管理 141
19.2.4 不用于执行的环境 142
19.2.5 eval()的环境 143
19.3 特殊的非严格模式的全局 144
19.4 小结 145
第 20章 非严格模式的全局环境中的动态执行 146
20.1 在全局环境中的eval 147
20.2 名字之争:对eval安全性的权衡 148
20.3 严格模式是执行限制而不是环境属性 149
20.4 直接调用与间接调用的对比 150
20.5 为什么本章标题下的代码是间接调用 151
20.6 eval()怎么返回结果 153
20.7 小结 154
第 21章 动态函数及其工作原理 155
21.1 动态创建函数的方法 156
21.1.1 得到函数的几种途径 156
21.1.2 几种动态函数的构造器 157
21.1.3 函数的3个组件 157
21.1.4 动态函数的创建过程 158
21.2 动态函数与其他函数的一致性 159
21.3 动态创建函数与间接调用eval()的唯一差异 159
21.4 小结 160
第五篇 从有序中抽离时间:并行的本质不是有序而是重复
第 22章 Promise的精华:then链 162
22.1 早期JavaScript中的并行逻辑 163
22.2 从回调到Promise的then链 164
22.2.1 then链与其他主要概念之间的关系 164
22.2.2 并生体:从then链的本质来理解时间剥离 165
22.3 then链的起始端:resolve()/reject()置值器 166
22.4 通过then链交付数据 168
22.4.1 p.then(f)中f的传入值 168
22.4.2 p.then(f)中f的返回值 169
22.5 小结 170
第 23章 then链中的异数:Thenable对象与类型模糊 171
23.1 Thenable是行为化的Promise 172
23.1.1 Thenable是通过特定界面向外界陈述自身值的对象 172
23.1.2 then方法需要有执行回调的潜在能力 173
23.2 Thenable值的可变性及其影响 174
23.3 Thenable中then()的返回值 176
23.4 then()的主动唤起与被动唤起 177
23.5 Thenable的概念转换与类型模糊 177
23.6 小结 178
第 24章 Promise类与子类 180
24.1 Promise类的应用:以“Hello world”程序为例 181
24.1.1 用三元组替代Promise的行为 181
24.1.2 执行器中的其他逻辑 182
24.2 类上的原型方法:以异常处理为例 182
24.3 子类及其构造方法的界面 184
24.3.1 定制执行器逻辑及其返回 184
24.3.2 定制构造方法的界面 185
24.4 小结 186
第 25章 精巧的设计:await/async 187
25.1 异步函数与异步上下文 188
25.1.1 异步上下文的独特之处 188
25.1.2 异步在多次调用的不同表现 189
25.2 await上演的帽子魔法 190
25.2.1 执行栈上的细节变化 190
25.2.2 处理数据x的详细逻辑 191
25.3 async/await以及yield等特殊的名字 193
25.4 小结 195
第 26章 并发与多线程 196
26.1 ECMAScript中的线程并发模型 197
26.1.1 多线程并发执行环境 197
26.1.2 资源争用:并发执行的核心冲突 198
26.2 工作线程及其调度 198
26.2.1 通知与数据交换 201
26.2.2 游离状态与调度模型 201
26.2.3 现实环境 201
26.3 持锁访问 202
26.3.1 Atomics.wait()的细节 205
26.3.2 lock()方法的使用以及它存在的问题 206
26.3.3 资源规划、竞争与死锁 208
26.4 小结 210
第 27章 并发在分布式环境中的应用 211
27.1 从无视时间到管理时间 211
27.2 静态规划的本质是假设系统不受时间流逝的影响 212
27.2.1 需要基于一个可通信网络 213
27.2.2 需要检测资源状态 214
27.2.3 需要带预备过程的两阶段提交 215
27.2.4 用一对完整的“请求/响应”来获取资源 215
27.3 游离状态在分布式系统中的问题 216
27.4 去中心化与分布式模型 217
27.5 小结 218
第六篇 致未来:新的语言特性
第 28章 动静之间的平衡:import() 220
28.1 ES6模块的主要问题 221
28.1.1 浏览器端的特殊性 221
28.1.2 服务器端的简单需求 222
28.1.3 ES6规范的选择 224
28.2 动态导入的模块 224
28.2.1 语法查错 225
28.2.2 决定时效性 226
28.3 import()的出现 226
28.4 浏览器生态下的动态导入 227
28.5 受ESM模块影响的网页脚本执行顺序 231
28.6 小结 232
第 29章 所有的组合:Promise.allSettled()和Promise.any() 233
29.1 组合的基本原则 234
29.1.1 通过组合来扩展系统的外延 234
29.1.2 寻求合理的补充 235
29.1.3 少即是多的理念 238
29.2 更多组合、更多选择 239
29.3 小结 241
第30章 与null的长期斗争:从 .到 242
30.1 使用null和undefined的一些最佳实践 243
30.2 空值检测的一些预期性质 245
30.3 问号的设计 246
30.3.1 短路运算与 .运算符的短路设计 246
30.3.2 是否存在一种新的语法设计风格 248
30.3.3 JavaScript运算符在设计上的限制 251
30.4 小结 252
第31章 块的魔法:类强化过程中的那些方案 254
31.1 代码的组织:形式分块 255
31.1.1 信息隐蔽 255
31.1.2 结构化 256
31.1.3 映射 256
31.1.4 在JavaScript中代码分块与作用域的关系 257
31.2 表达式级别的词法作用域 257
31.3 围绕类或对象的信息隐蔽进行的设计 260
31.3.1 字段:TC39对信息隐蔽的理解 261
31.3.2 块:类构造与实例构造过程的组织与联系 264
31.3.3 类的进一步强化:块化和注解化 266
31.4 有关作用域的两点补充设计 268
31.5 小结 269
第32章 计算与应用:数据类型设计上的强化或概念扩展 271
32.1 JavaScript的内建数据类型与标准库 273
32.1.1 对象与标准库 273
32.1.2 标准库的结构 273
32.1.3 强化标准库的进展 274
32.2 在基础类型中对有序类型的进一步设计 275
32.3 在内存与线程相关技术中对应用环境的更多考量 278
32.4 宿主行为规范 280
32.5 小结 283
第33章 最后的屏障:顶层await 285
33.1 模块的状态 286
33.2 模块的顶层代码 287
33.3 模块顶层代码中的await 288
33.4 浏览器环境下的异步 290
33.5 最后一块落井石 291
33.6 小结 294
附录A 22道测试题 295
附录B 测试题答案及解析 299
猜您喜欢

读书导航