产品特色
编辑推荐
JavaScript语言有很多复杂的概念,但却用简单的方式体现出来(比如回调函数),因此,JavaScript开发者无需理解语言内部的原理,就能编写出功能全面的程序。然而,JavaScript的这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发者,如果没有认真学习,也无法真正理解语言本身的特性。正是因为绝大多数人不求甚解,一遇到出乎意料的行为就认为是语言本身有缺陷,进而把相关的特性加入黑名单,久而久之就排除了这门语言的多样性,人为地使它变得不完整、不安全。
“你不知道的JavaScript”系列就是要让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书介绍了该系列的两个主题:“类型和语法”以及“异步和性能”。掌握了这些知识之后,无论什么技术、框架和流行词语,你都能轻松理解。
内容简介
JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解。本套书直面当前JavaScript开发人员不求甚解的大趋势,深入理解语言内部的机制,全面介绍了JavaScript中常被人误解和忽视的重要知识点。本书是其中卷,主要介绍了类型、语法、异步和性能。
作者简介
Kyle Simpson
作家、培训师、讲师、开源社区的活跃成员,推崇开放的互联网,对JavaScript、HTML5、实时/端对端通信和Web性能有深入研究。
单业
计算机专业硕士,软件工程师,曾供职于多家软件公司,从事软件开发工作,现居于上海。负责本书第二部分“异步和性能”的翻译。
姜南
从事过国内外金融、通信、移动互联网、数字出版等领域的IT系统开发工作,擅长的技术有Java、C#、HTML5、JavaScript、iOS、Android等。长期在独立技术博客——酷壳(coolshell.cn)发表翻译文章。负责本书首部分“类型和语法”的翻译。
目录
目录
前言 XI
第一部分 类型和语法
序 2
第1 章 类型 3
1.1 类型 4
1.2 内置类型 4
1.3 值和类型 6
1.3.1 undefined 和undeclared 6
1.3.2 typeof Undeclared 7
1.4 小结 10
第2 章 值 11
2.1 数组 11
2.2 字符串 13
2.3 数字 15
2.3.1 数字的语法 16
2.3.2 较小的数值 18
2.3.3 整数的安全范围 19
2.3.4 整数检测 20
2.3.5 32 位有符号整数 20
2.4 特殊数值 21
2.4.1 不是值的值 21
2.4.2 undefined 21
2.4.3 特殊的数字 23
2.4.4 特殊等式 27
2.5 值和引用 28
2.6 小结 31
第3 章 原生函数 33
3.1 内部属性[[Class]] 34
3.2 封装对象包装 35
3.3 拆封 36
3.4 原生函数作为构造函数 37
3.4.1 Array(..) 37
3.4.2 Object(..)、Function(..) 和RegExp(..) 40
3.4.3 Date(..) 和Error(..) 41
3.4.4 Symbol(..) 42
3.4.5 原生原型 43
3.5 小结 45
第4 章 强制类型转换 46
4.1 值类型转换 46
4.2 抽象值操作 47
4.2.1 ToString 48
4.2.2 ToNumber 52
4.2.3 ToBoolean 53
4.3 显式强制类型转换 56
4.3.1 字符串和数字之间的显式转换 57
4.3.2 显式解析数字字符串 62
4.3.3 显式转换为布尔值 65
4.4 隐式强制类型转换 67
4.4.1 隐式地简化 67
4.4.2 字符串和数字之间的隐式强制类型转换 68
4.4.3 布尔值到数字的隐式强制类型转换 71
4.4.4 隐式强制类型转换为布尔值 72
4.4.5 || 和 73
4.4.6 符号的强制类型转换 76
4.5 宽松相等和严格相等 77
4.5.1 相等比较操作的性能 .77
4.5.2 抽象相等
4.6 抽象关系比较 89
4.7 小结 91
第5 章 语法 92
5.1 语句和表达式 92
5.1.1 语句的结果值 93
5.1.2 表达式的副作用 95
5.1.3 上下文规则 99
5.2 运算符优先级 104
5.2.1 短路 107
5.2.2 更强的绑定 107
5.2.3 关联 108
5.2.4 释疑 110
5.3 自动分号 111
5.4 错误 113
5.5 函数参数 115
5.6 try..finally 117
5.7 switch 120
5.8 小结 122
附录A 混合环境JavaScript 123
第二部分 异步和性能
序 136
第1 章 异步:现在与将来 138
1.1 分块的程序 139
1.2 事件循环 141
1.3 并行线程 143
1.4 并发 148
1.4.1 非交互 150
1.4.2 交互 150
1.4.3 协作 154
1.5 任务 156
1.6 语句顺序 157
1.7 小结 159
第2 章 回调 161
2.1 continuation 162
2.2 顺序的大脑 163
2.2.1 执行与计划 164
2.2.2 嵌套回调与链式回调 165
2.3 信任问题 169
2.3.1 五个回调的故事 170
2.3.2 不只是别人的代码 171
2.4 省点回调 173
2.5 小结 176
第3 章 Promise 178
3.1 什么是Promise 179
3.1.1 未来值 179
3.1.2 完成事件 183
3.2 具有then 方法的鸭子类型 188
3.3 Promise 信任问题 190
3.3.1 调用过早 190
3.3.2 调用过晚 191
3.3.3 回调未调用 192
3.3.4 调用次数过少或过多 193
3.3.5 未能传递参数/ 环境值 193
3.3.6 吞掉错误或异常 194
3.3.7 是可信任的Promise 吗 195
3.3.8 建立信任 197
3.4 链式流 198
3.5 错误处理 206
3.5.1 绝望的陷阱 208
3.5.2 处理未捕获的情况 209
3.5.3 成功的坑 211
3.6 Promise 模式 212
3.6.1 Promise.all([ .. ]) 212
3.6.2 Promise.race([ .. ]) 213
3.6.3 all([ .. ]) 和race([ .. ]) 的变体 216
3.6.4 并发迭代 217
3.7 Promise API 概述 219
3.7.1 new Promise(..) 构造器 219
3.7.2 Promise.resolve(..) 和Promise.reject(..) 219
3.7.3 then(..) 和catch(..) 220
3.7.4 Promise.all([ .. ]) 和Promise.race([ .. ]) 221
3.8 Promise 局限性 222
3.8.1 顺序错误处理 222
3.8.2 单一值 223
3.8.3 单决议 225
3.8.4 惯性 227
3.8.5 无法取消的Promise 230
3.8.6 Promise 性能 231
3.9 小结 233
第4 章 生成器 234
4.1 打破完整运行 234
4.1.1 输入和输出 236
4.1.2 多个迭代器 239
4.2 生成器产生值 243
4.2.1 生产者与迭代器 243
4.2.2 iterable 246
4.2.3 生成器迭代器 247
4.3 异步迭代生成器 250
4.4 生成器+Promise 254
4.4.1 支持Promise 的Generator Runner 256
4.4.2 生成器中的Promise 并发 258
4.5 生成器委托 262
4.5.1 为什么用委托 264
4.5.2 消息委托 264
4.5.3 异步委托 268
4.5.4 递归委托 268
4.6 生成器并发 269
4.7 形实转换程序 273
4.8 ES6 之前的生成器 279
4.8.1 手工变换 280
4.8.2 自动转换 284
4.9 小结 285
第5 章 程序性能 287
5.1 Web Worker 288
5.1.1 Worker 环境 290
5.1.2 数据传递 291
5.1.3 共享Worker 291
5.1.4 模拟Web Worker 293
5.2 SIMD 293
5.3 asm.js 295
5.3.1 如何使用asm.js 优化 295
5.3.2 asm.js 模块 296
5.4 小结 298
第6 章 性能测试与调优 299
6.1 性能测试 99
6.1.1 重复 300
6.1.2 Benchmark.js 301
6.2 环境为王 303
6.3 jsPerf.com 305
6.4 写好测试 309
6.5 微性能 309
6.5.1 不是所有的引擎都类似 312
6.5.2 大局 314
6.6 尾调用优化 316
6.7 小结 318
附录A asynquence 库 319
附录B 高级异步模式 339
你不知道的JavaScript(中卷):深度解析现代JavaScript核心机制 引言 JavaScript,这个曾被认为是“简单脚本语言”的语言,如今已成为构建现代Web应用、服务器端程序,甚至桌面应用和移动应用的基石。其飞速发展的生态和不断演进的标准,让无数开发者沉醉其中,也为深入理解其内在机制带来了挑战。本书《你不知道的JavaScript(中卷)》并非一本简单的入门指南,而是一次对JavaScript核心机制的深度挖掘,旨在帮助开发者超越表面的API调用,理解语言底层的工作原理,从而写出更健壮、更高效、更易于维护的代码。 本书专注于JavaScript的核心语言特性,特别是那些经常被误解、被忽略,但却至关重要的概念。它将带领你穿越JavaScript的语言规范,解析那些“看不见的”机制,揭示语言设计背后的思想,让你真正掌握JavaScript这门强大的语言。 第一部分:作用域与闭包 (Scope and Closures) 作用域是JavaScript中一个极其重要的概念,它决定了变量的可访问性和生命周期。许多开发者在编写代码时,对作用域的理解仅停留在“函数内部的变量是局部的”。然而,JavaScript的作用域机制远比这复杂得多。 词法作用域 (Lexical Scoping): 本卷将深入探讨JavaScript所采用的词法作用域模型。这意味着变量的作用域在代码编写时就已经确定,而不是在代码运行时才确定。我们将分析作用域链 (Scope Chain) 的形成机制,以及JavaScript引擎如何通过作用域链查找变量。理解词法作用域是理解闭包的基础。 函数作用域与块级作用域 (Function Scope vs. Block Scope): 通过对比 `var`、`let` 和 `const` 的不同行为,我们将详细阐述函数作用域和块级作用域的区别,以及它们对变量生命周期和可访问性的影响。掌握块级作用域对于编写更清晰、更易于管理的现代JavaScript代码至关重要。 闭包 (Closures): 闭包是JavaScript中最强大也最容易被误用的特性之一。本书将彻底解构闭包的概念,解释它是如何形成的,以及它与词法作用域的关系。我们将通过丰富的实例,展示闭包在模块化、数据封装、函数工厂、延迟执行等场景中的实际应用,并分析其潜在的内存泄漏风险及规避方法。理解闭包,意味着你掌握了JavaScript函数式编程的精髓。 第二部分:对象与原型 (Objects and Prototypes) JavaScript的面向对象模型与传统的类继承模型有着本质的区别。本书将深入剖析JavaScript的对象模型,揭示其基于原型的继承机制。 对象字面量与构造函数 (Object Literals and Constructor Functions): 我们将从最基础的对象创建方式——对象字面量和构造函数入手,理解它们是如何创建对象的,以及它们与 `new` 关键字的关系。 `this` 关键字的陷阱与优雅 (The `this` Keyword: Traps and Elegance): `this` 关键字是JavaScript中最令人困惑的关键字之一,它的指向在不同的调用上下文中会发生变化。本书将系统性地分析 `this` 的绑定规则,包括默认绑定、隐式绑定、显式绑定 (`call`、`apply`、`bind`) 以及通过 `new` 关键字绑定的情况。通过大量的实例,帮助你彻底掌握 `this` 的指向,避免常见的错误。 原型链 (Prototype Chain): JavaScript的继承是通过原型链实现的。我们将详细讲解原型 (`prototype`) 和原型链的概念,以及对象是如何通过原型链查找属性和方法的。理解原型链是理解JavaScript面向对象编程的关键。 `__proto__` 和 `Object.create()` (The `__proto__` and `Object.create()`): 本卷将介绍 `__proto__` 属性(虽然不推荐直接使用)和 `Object.create()` 方法,它们是操作和理解原型链的重要工具。通过 `Object.create()`,你可以更精细地控制对象的原型,从而实现更灵活的继承模式。 构造函数、原型和实例的关系 (Constructor, Prototype, and Instance Relationships): 深入理解构造函数、其 `prototype` 属性以及实例对象三者之间的错综复杂的关系,能够帮助你更清晰地认识JavaScript的面向对象本质。 第三部分:异步编程 (Asynchronous Programming) 在现代Web开发中,异步编程几乎无处不在。从网络请求到用户交互,再到定时任务,JavaScript都需要处理大量的异步操作。本书将全面讲解JavaScript的异步编程模型。 事件循环 (Event Loop): 本卷将深入解析JavaScript的事件循环机制。我们将理解调用栈 (Call Stack)、任务队列 (Task Queue)(包括宏任务和微任务)是如何协同工作的,以及它们如何实现异步操作的非阻塞执行。清晰地理解事件循环是掌握JavaScript异步编程的基础。 回调函数 (Callback Functions): 回调函数是JavaScript中最早的异步处理方式。我们将分析回调函数的优点和缺点,特别是“回调地狱” (Callback Hell) 的问题,并探讨如何通过一些模式来改善代码的可读性。 Promise: Promise 是ES6引入的,用于更优雅地处理异步操作。本书将详细讲解Promise的状态(pending, fulfilled, rejected),Promise的链式调用,以及如何使用 `then`、`catch` 和 `all` 等方法来管理异步流程。Promise极大地简化了异步编程,使得代码逻辑更加清晰。 Generator 函数: Generator 函数是ES6引入的一种特殊的函数,它可以暂停执行并稍后恢复。我们将讲解Generator函数的语法,以及如何使用 `yield` 关键字来控制函数的执行流程。Generator函数为异步编程提供了更强大的控制力,并且是实现协程 (Coroutines) 的基础。 Async/Await: Async/Await 是ES7(ES2017)引入的,它建立在Promise的基础上,提供了更加同步风格的异步编程体验。本书将深入讲解 `async` 和 `await` 关键字的用法,以及它们如何结合Promise,使得异步代码的编写和阅读变得更加直观和容易。你将学会如何用同步的思维来编写异步代码,极大地提升开发效率和代码质量。 结论 《你不知道的JavaScript(中卷)》不是一本“读完就懂”的书,它是一份邀请,邀请你踏上深入探索JavaScript之旅。通过对作用域、闭包、对象、原型以及异步编程等核心机制的细致剖析,本书将帮助你建立起对JavaScript更深刻、更本质的理解。掌握了这些基础,你将能够更自信地驾驭JavaScript这门语言,写出更高效、更健壮、更具表现力的代码,真正成为一名JavaScript的“内行”。无论你是希望巩固基础、解决疑难杂症,还是为进一步探索JavaScript的高级特性打下坚实基础,本书都将是你不可或缺的宝贵资源。