你不知道的 JavaScript
前言
《你不知道的 JavaScript》 是一部由 Kyle Simpson 所著的 JavaScript 书籍。这本书旨在深入探讨 JavaScript 语言的核心概念,特别是一些常常被开发者误解或忽视的部分。
这本书是一本深入研究 JavaScript 的经典之作,对于想要提高他们的 JavaScript 编程技能的开发者来说是一本非常有价值的资源,可以帮助你更深入地理解 JavaScript 的内部工作原理。
推荐理由
《你不知道的 JavaScript》 是我看完 《JavaScript 高级程序设计》 后看的第二部前端书籍,总共分为上、中、下三卷,每一卷都能带给我新的收获。其中内容深入的讲解了前端开发过程中可能不了解但应该掌握的基本知识,让我受益匪浅。像上卷中的 作用域 部分、中卷中的 异步与性能部分 都让我对于项目中 JS 的行为有了更深刻的认识。
同时它也是第一部我读得入迷的前端书籍,其中的一些概念让我感到有趣。像 JS 编译、词法作用域,以及生成器和 Promise 结合产生的 异步函数,这些无不让我感叹前人的智慧。
上卷
第一部分 作用域和闭包
第 1 章 作用域是什么
本章讲述了有关作用域相关的知识,从编译原理开始,一步一步了解作用域的本质,还介绍了与作用域相关的 LHS、RHS 查询。
第 2 章 词法作用域
第 1 章讲述了什么是作用域,第 2 章则带我们了解作用域两种工作模型的其中一种:词法作用域。其中讲述了词法作用域的基本概念,以及词法作用域中数据的查找方式,最后介绍了如何欺骗词法以及欺骗词法所带来的性能问题。
第 3 章 函数作用域和块作用域
这一章介绍了函数作用域和块作用域的概念,同时还介绍了函数作用域如何隐藏其内部实现、规避代码冲突,以及函数的一些有趣特性:匿名函数和具名函数、立即执行表达式。最后讲解了块作用域的相关知识,以及他带来的一些好处。
第 4 章 提升
本章讲解了 JavaScript 世界中的独特特性:提升。本章内容描述了编译器进入一个新的作用域时是如何工作的,即提升的原理是什么。
第 5 章 作用域闭包
本章带我们理解 JS 中最重要的概念之一:闭包。内容讲述了闭包是什么,闭包是如何产生及工作的,还扩展了很多与闭包相关的知识,比如模块。
第二部分
第 1 章 关于 this
本章说明了 this 是一个上下文对象,在 js 中 this 是可变的,这导致开发者很难搞清除当前作用域的 this 是什么。
第 2 章 this 全面解析
本章深入讲解了关于 this 是什么的问题,大部分情况下 this 指向调用它的对象,但我们可以通过 js 提供的函数方法 call、apply、bind 来显式修改作用域中的 this;同时也可以通过 new 关键词来绑定 this 到对象实例上。
本章还讲解了关于 this 绑定的优先级,new 关键词优先级比函数方法 call、apply、bind 具有更高的优先级;以及箭头函数中的 this 总是取决于上层作用域中的 this。
第 3 章 对象
本章讲解了对象的形式,与对象类型;还介绍了对象引用与对象复制的区别、修改对象属性的 configuarable、getter 与 setter;最后讲解了遍历对象的几种方式。
第 4 章 混合对象 “类”
本章介绍了面向对象中必不可少的部分:类。讲解了类的理论,类的设计模式以及 js 中类的实现方式。同时说明了类的继承、多态、多重继承能力。
我们还可以通过混入将多个类关联起来,本章讲解了多种类混入的方式。
第 5 章 原型
这章开始讲解了 js 中的基石:原型。原型是对象身上的内置属性,它指向了一个函数的原型对象,通过这种方式来实现继承属性。我们可以对属性进行设置,也可以这部原型链上层的属性。同时告诉了我们 js 中的类并不是真正的类模式,而是通过原型及原型继承模拟的一个伪类模式。
第 6 章 行为委托
本章讲解了类与行为委托的差异,让我们进一步的了解类与原型是不相同的两个东西。同时推荐了类与行为委托的最近实践,并告诉我们一些不好的使用类与行为委托的方式。
中卷
第一部分 类型和语法
第 1 章 类型
本章讲解了 js 中的数据类型,包括内置类型、类型检测、值类型的概念,帮助我们初步的了解 js 类型机制。
第 2 章 值
本章更进一步的讲解了几种值类型,并讲解了操作他们的方式,其中对数字类型有深入讲解,包括数字类型的浮点值、整数安全范围、整数检测、特殊数值。还说明了值和引用的区别,以及 js 中值和引用的操作语法。
第 3 章 原生函数
本章讲解了 js 中的原生函数,常用的函数有:
- String()
- Number()
- Boolean()
- Array()
- Object()
- Function
- RegExp()
- Date()
- Error()
- Symbol()
可以将这些函数当作构造函数构造对应的对象,这些对象有些是基本数据类型的封装对象。通过 typeof 查看这些对象会返回 object,这类对象都包含一个内部属性 [[Class]],我们可以通过 Object.prototype.toString.call(obj) 来查看 [[Class]] 的属性值。
本章还讲解了包装对象,以及包装对象如何获取对应的基本值,同时介绍了关于 Object()、Function()、RegExp()、Date()、Error()、Symbol() 的相关执行,以及它们对应的原型对象与原型属性。
第 4 章 强制类型转换
本章介绍了 js 中经常被人忽略的情况:强制类型转换。说明了 js 中会出现类型转换的情况,以及 js 中数据类型的抽象操作,这些抽象操作在内部进行,主要是定义了内部的转换规则,如 ToString、ToPrimitive、ToNumber、ToBoolean。还有真值与假值、假值对象与类型转换的一些细节。
还讲解了关于位运算符对于一些数据类型进行类型转换的操作,使用 ToInt32 来转换为 number 类型,以及字符串解析为数字的一些操作与细节。
之后讲解了关于隐式转换的知识、逻辑运算符以及逻辑运算符的返回值的知识。着重介绍了关于宽松相等与严格相等的区别,以及宽松相等导致的数据类型隐式转换的隐晦知识。
第 5 章 语法
介绍了 js 的语法,语法是由语句组成的有意义的组合,每个语句都有它的返回值,还介绍了表达式的副作用、上下文规则,还带我们深入了解了 js 中一些令人感到疑惑的语法解析规则。
之后介绍了 js 的运算符优先级、逻辑运算、逻辑短路、自动分号、错误、try..finally..、switch。
第二部分 异步和性能
第 1 章 异步:现在与将来
讲解了 js 异步的知识,js 中的异步指一部分在现在执行,一部分在未来执行,其中涉及了事件循环的相关知识,包括并行线程、并发请求、数据共享、并非协作等知识;以及 js 的新概念:任务队列,建立在事件循环之上。
之后讲解了 js 引擎执行语句的顺序,以及 js 编译代码时可能做的一些优化。
第 2 章 回调
本章先介绍了我们如何通过回调来获取到将来发生的事件的结果值,然后说明了使用回调来完成异步操作的一些缺点,比如嵌套、链式回调,这些会导致回调地狱的发生,这类问题会让我们的代码变的脆弱,很难维护。
第 3 章 Promise
本章讲解了 ES6 出现的异步 Api: Promise,真正意义上的解决了异步编程困难的问题。Promise 译为承诺,它会包装我们的代码至少会被调用一次来获取到异步事件的结果。
Promise 解决了异步回调的很多问题,比如调用过早、调用过晚、回调未调用、调用次数过多或过少、未传递参数、吞掉错误或异常等问题。这些问题都是由于代码不可信任导致的,而 Promise 给了我们建立代码信任的能力。
还介绍了 Promise 的链式调用,可以使我们编写更优雅的异步代码,以及 Promise 状态、错误处理、Promise 错误处理的一些问题。
之后介绍了 Promise 的 API 以及我们可以使用这些 API 做些什么,包括 resolve、reject、then、catch、all、race 等等。
最后说明了 Promise 的一些局限性,比如顺序错误处理、单一值、单决议、惯性、无法取消、性能等问题。
第 4 章 生成器
介绍了 ES6 中一种强大的流程控制特性:生成器。它允许我们控制代码的执行,允许内部与外部的参数交换;同时扩展了关于迭代器的知识、如何实现自己的迭代器以及一些内置迭代器的数据类型。
还介绍了关于异步迭代生成器的知识,它可以用来执行有关异步的代码,也可以同步处理异步错误,这些实现是基于生成器和 Promise 的结合,通过两者结合我们可以得到目前 ECMA 规范支持的异步函数。
之后又说明了生成器委托相关的知识,生成器内部允许我们调用另一个生成器并使用当前生成器来控制代码的执行。
最后介绍了一些生成器的使用场景,比如并发、形式转换程序。以及如何将生成器编译为 ES5 代码以在旧浏览器中使用。
第 5 章 程序性能
本章探讨了程序性能方面的知识,我们可以在浏览器中开启一个 Worker 来并行独立的运行程序,或 SIMD 技术实现并行操作的指令,以及 js 的子集 asm.js 可以让我们解决内存分配、垃圾回收和作用域访问导致的性能问题。
第 6 章 性能测试与调优
本章首先介绍了我们应该如何对程序的性能进行测试,我们可以使用 Benchmark.js 来运行我们的程序以得出性能,还需要注意环境的重要性、引擎优化可能带来的性能测试差异,还能通过 jsPerf.com 网站对不同的运行环境运行测试我们的程序性能,以及测试完整性的重要。
最后告诉了我们对于程序的性能应该关注于关键的部分,不要过多的在意对于程序没有影响部分的性能损耗,以及 ES6 中的函数尾调用优化。
下卷
第一部分 起步上路
第 1 章 深入编程
本章面向从未了解过编程的人,讲解了有关于编程的基础知识,比如:表达式、语句、变量、运算符、数据类型、注释、判断、循环、函数、作用域。
第 2 章 深入 JavaScript
本章讲解了 js 中的编程,比如 js 中的值类型、对象、内置对象的方法、比较方法、作用域提升、严格模式、函数作为值、闭包、立即调用表达式、this 标识符、原型、polyfilling 是什么以及它的作用、以及与浏览器深度集成的可在 js 中使用的 API。
第 3 章 深入 “你不知道的 JavaScript” 系列
本章介绍了在其他两卷中已经讲解的相关知识,通过这些知识我们可以深入 js 中的作用域、闭包、this 和原型、类型和语法、异步和性能的相关知识。
第二部分
第 1 章 ES? 现在与未来
本章开始讲解了关于 ECMAScript 版本的命名与变化,如何使用工具将快速变化的 ES 中的新的 API 转换为在旧浏览器中支持的代码。
第 2 章 语法
本章介绍了 ES6 中的一些新的语法,比如块作用域声明、块作用域函数、扩展运算符、剩余参数、默认参数、解构、计算属性、通过 __proto__ 设置原型、super 对象、模板字面量、箭头函数、for..of 循环、正则的变化、数字字面量扩展。
第 3 章 代码组织
本章介绍了了 js 中的一些高级特性,比如迭代器、生成器、模块、类等等。
第 4 章 异步流控制
本章解决了 ES6 中的异步接口的变化,包括 Promise、生成器和 Promise 组合得出的异步模式。
第 5 章 集合
本章介绍了 ES6 中的集合数据类型,详细讲解了如 TypedArray、Map、WeakMap、Set、WeakSet 等数据类型。
第 6 章 新增 API
本章讲解了 ES6 中新增的一些 API,如 Array 新的原型方法、静态方法、Object 新的原型与静态方法、Math 的新方法、Number 的新方法、String 的新方法。
第 7 章 元编程
本章介绍了元编程的概念,元编程即对代码进行操作的代码,介绍了如:函数名称推导、元属性、公开符合、代理、反射、特性检测、尾调用等知识。
第 8 章 ES6 之后
本章介绍了在 ES6 之后可能或已经出现的一些特性,如异步函数、Object.observe、幂运算、对象属性与 ...、Array.prototype.includes、SIMD、WASM。
