阅读总结
一本 12 年修订(09 年初版)的过时的书,很多点在 ES6 甚至 ES5 之后都没有再关心的必要了。也可能是年代久远的原因,作者的很多观点看上去带有比较强的主观性。总之,在今天,本书已经带来不了太多的收获了。
[toc]
第 1 章 精华
- JavaScript 糟粕的比重大,但有一些非常精华的部分
- 标准委员会无法移除缺陷特性,需要开发者自己定义精华的子集
为什么要使用 JavaScript
分析 JavaScript
- 函数式特性
- 弱类型
- 对象字面量表示法
- 原型继承
- 原型继承
- 全局变量
一个简单的试验场
第 2 章 语法
- 介绍精华部分的语法,概述其语言结构
- 使用铁路图(语法图)描述语法
空白
标识符
- 由一个字母开头,可包含字母、数字、下划线
数字
- 只有一个数字类型
- 64 位浮点数
- 没有整数类型
- 避免了短整型溢出等数组类型导致的错误
- Math
字符串
-
/
转义 - 没有字符类型,只需要创建一个字符串表示字符
语句
- 条件、循环、强制跳转等语句
表达式
-
%
是求余,而不是求模 -
()
函数调用运算符
字面量
- 对象字面量
- 数组字面量
函数
第 3 章 对象
- 可变的键控集合
- 属性的容器
- 无类型
- 原型链
对象字面量
var obj = { a: 1 }
检索
.
[ ]
更新
引用
原型
Object.create
- 原型链、委托、动态
反射
- 检查对象属性
hasOwnProperty
枚举
for...in
删除
-
delete a.b
不会删除原型链上的属性
减少全局变量污染
- 作为一个全局变量的属性
第 4 章 函数
- JavaScript 接近于完美的函数设计
函数对象
Function.prototype
Function.prototype.constructor
函数字面量
var f = function () {}
调用
- 调用一个函数会暂停当前函数的执行
方法调用模式
-
this
指向方法所属的对象
函数调用模式
-
this
指向全局对象
构造器调用模式
-
this
指向新对象
Apply 调用模式
-
this
指向第一个参数
参数
-
arguments
并不是一个好的设计
返回
-
new
调用,且返回值不是对象,则返回this
异常
throw exception
-
exception
包含name
和message
属性 -
try...catch
中通过exception
的name
来区分错误类型
扩充类型的功能
Function.prototype.method
递归
- 自相似问题
- 尾递归优化
作用域
闭包
回调
模块
- 使用函数和闭包来构造模块
级联
- 函数链
柯里化
记忆
第 5 章 继承
- 对象从其他对象继承
伪类
- 构造器函数是糟糕的设计
- 隐藏了原型继承的本质(看上去像不完整的类继承)
- 没有
new
时会破坏全局环境 - 许多复杂的类层次结构产生的原因是静态类型检查的约束,而 JavaScript 完全摆脱了约束,因此在代码重用上可以有更多更好的选择
对象说明符
- 即
object
形式的参数
原型
- 专注于对象,概念上更简单
函数化
- 利用闭包隐藏私有变量
部件
- 事件处理部件的
第 6 章 数组
- 数组是一段线性分配的内存,通过整数计算偏移并访问其中的元素,是一种性能出色的数据结构
- 但 JavaScript 并没有真正的数组,只有类数组特性的对象,以字符串作为数组下标
数组字面量
长度
- 最大整数属性名 +1
- 可以直接设置
length
,设小将删除剩余元素
删除
-
splice
,会导致后续的每一个 key-value 变化,因此性能不高
枚举
容易混淆的地方
- 判断
Object
和Array
类型
方法
指定初始值
第 7 章 正则表达式
- JavaScript 的正则表达式借鉴子 Perl
- JavaScript 中正则表达式相较于等效的字符串处理有显著的性能优势
- 简洁但阅读性极差,难以修改
一个例子
- 匹配 URL
- 匹配数字
结构
- 标识符
g, i, m(多行)
-
RegExp
对象,反斜杠在字符串下需要转义,通常需要双写反斜杠
元素
正则表达式分支
|
正则表达式序列
- 一个序列包含一个或多个正则表达式因子,每个因子可以跟随一个量词
正则表达式因子
- 一个因子可以是一个字符、一个由圆括号包围的组、一个字符类、一个转义序列
正则表达式转义
-
\1
是指向分组 1 所捕获到的文本的一个引用,所有能被再次匹配,可以用来搜索重复的单词
正则表达式分组
- 捕获型
- 非捕获型
- 向前正向匹配(不好的特性)
- 向前负向匹配(不好的特性)
正则表达式字符集
- 匹配 ASCII 字符的
正则表达式字符转义
- 需要被转义的
-/[\]^
正则表达式量词
- 使用贪婪性匹配
第 8 章 方法
几个不熟悉但实用的
String.prototype.lastIndexOf
Array.prototype.lastIndexOf
String.protoype.search
String.fromCharCode
第 9 章 代码风格
第 10 章 优美的特性
- 精简的 JavaScript
- 函数是顶级对象
- 基于原型继承的动态对象
- 对象字面量和数组字面量
- 特性成本
附录 A 毒瘤
- 一些难以避免的问题特性
全局变量
作用域
自动插入分号
保留字
Unicode
typeof
parseInt
- 遇到非数字会停止解析而不抛错误
- 0 开头的字符串会被基于八进制求值
+
浮点数
-
0.1 + 0.2 = 0.30000000000000004
但这是遵循二进制浮点数算数标准的
NaN
-
NaN === NaN
false
伪数组
假值
-
null == undefined
true
hasOwnProperty
- 是方法而不是以运算符
对象
附录 B 糟粕
- 可以避免的问题特性
==
with
eval
- 同样的还有 Function 构造器、接受字符串参数时的 setTimeout/setInterval
continue 语句
- 性能不好
switch 穿越
缺少块的语句
++ --
- 鼓励了一种不够谨慎的编程风格
位运算符
- JavaScript 的执行环境接触不到硬件,因此位运算性能差
function 语句对比 function 表达式
类型的包装对象
- 避免使用
new Object
等
new
void
附录 C - E 跳过