读书笔记: JavaScript 语言精粹
《JavaScript: The Good Parts》
JavaScript 曾是“世界上最被误解的语言”,因为它担负太多的特性,包括糟糕的交互和失败的设计。
本书拨开了 JavaScript 沾污的外衣,抽离出一个具有更好可靠性、可读性和可维护性的 JavaScript 子集,让你看到一门优雅的、轻量级的和非常富有表现力的语言。
第一章 精华 - Good Parts
第二章 语法 - Grammar
1、注释
注释应该被优先用来提高程序的可读性。但是没有用的注释比没有注释更糟糕。
块注释 /* */
的字符也有可能同时出现在正则表达式中,所以块注释对于被注释的代码块来说是不安全的。应尽量使用 行注释 //
来代替 块注释 /* */
。
2、数字
JavaScript 中只有一个数字类型,它在内部被表示为64位的浮点数。
NaN
是一个数值,表示一个不能产生正常结果的运算结果。它不等于任何值,包括它自己。
Infinity
表示所有大于 1.79769...e+308
的值。
3、语句
以下值被当做假 false
false
null
undefined
- 空字符串
' '
- 数字
0
- 数字
NaN
其他所有的值被当做真,包括 true
、字符串 "false"
,以及其他的对象。
第三章 对象 - Objects
JavaScript 的简单数据类型包括:数字、字符串、布尔值、null
值和undefined
值,其他所有值都是对象。
数组是对象,函数是对象,正则表达式是对象,当然,对象也是对象。
1、检索对象中的值
可以采用 []
后缀中包含一个字符串表达式的方式,比如 stooge["first-name"]
。
JavaScript 的标识符中包含连接符
-
是不合法的,但是允许包含下划线_
。
如果字符串表达式是一个字符串字面量,而且是一个合法的 JS 标识符且不是保留字,可以用 .
表示法代替,比如 stooge.firstName
。优先考虑此种表示法,因为它更紧凑且可读性更好。
2、枚举
for in
语句可用来遍历一个对象中的所有属性名,包括函数和原型中的属性。最常用的过滤器是 hasOwnProperty
方法获取对象自身属性,以及使用 typeof
来排除函数。
1 | var name; |
3、减少全局变量污染
最小化使用全局变量的方法之一是为应用创建一个唯一的全局变量,将全局性的资源纳入一个名称空间之下。
使用闭包来进行信息隐藏的方式,也是另一种有效减少全局变量的方法。
第四章 函数 - Functions
1、函数对象
一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的父函数的参数和变量。
通过函数字面量创建的函数对象包含一个连到外部上下文的连接。这被称为闭包。它是 JavaScript 强大表现力的来源。
2、调用
JavaScript 是一门基于原型继承的语言。
3、模块
模块模式的一般形式是:一个定义了私有变量和函数的函数;利用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把它们保存到一个可以访问到的地方。
使用模块模式就可以摒弃全局变量的使用。它促进了信息隐藏和其他优秀的设计模式实践。
4、级联
有一些方法没有返回值。如果让这些方法返回this
,而不是undefined
,就可以启用级联。
5、柯里化
柯里化,也常译为“局部套用”,是把多参数函数转换为一系列单参数函数并进行调用的技术。
第五章 继承 - Inheritance
在基于类的语言中,对象是类的实例,并且类可以从另一个类继承。JavaScript 是一门基于原型的语言,这意味着对象直接从其他对象继承。
1、伪类
通过构造器函数产生对象:采用构造器调用模式,即用 new
前缀去调用一个函数时,函数执行的方式会被修改。
伪类原本设计用于向面向对象靠拢,然而怪异的设计增加了污染全局变量的风险,以及没有私有环境等,所以需要慎重选择。
2、对象说明符
通过给构造器传递一个 JSON
对象,让代码更易阅读,而且不用顾虑多个参数的顺序。
3、原型
一个新对象可以继承一个旧对象的属性。
Object.create()
方法规范化了原型式继承。
1 | var person = { |
4、函数化
从构造一个可以生成对象的函数开始,在这个对象A内部拥有一些变量(可以看做私有),同时内部还拥有一个对象B,对象B可以通过自己内部的特权方法访问对象A内的私有变量和方法,最后我们返回对象B。
- 创建一个新对象。方法可以是任意的:对象字面量、
new
构造器函数、Object.create()
构造一个已经存在的对象的新实例、其他任何可以返回一个对象的函数。 - 有选择地定义私有实例变量和方法。
var
语句定义的普通变量。 - 给这个新对象扩充方法。这些方法拥有特权去访问参数,以及上一步中定义的变量。
- 返回那个新对象。
函数化模式有很大的灵活性。它相比伪类模式不仅带来的工作更少,还让我们得到更好的封装和信息隐藏,以及访问父类方法的能力。
5、部件
没懂这个是干啥的。
第六章 数组
JavaScript 提供了一种类数组特性的对象,它的属性的检索和更新的方式与对象一模一样,只不过多一个可以用整数作为属性名的特性。数组有自己的字面量格式。数组也有一套非常有用的内置方法。
1、长度 Length
length
属性的值是这个数组的最大整数属性名加上 1
,它不一定等于数组里的属性的个数。
1 | var myArray = []; |
可以设置 length
的值。设置更大的 length
不会给数组分配更多的空间,而把 length
设小,将导致所有下标大于等于新的 length
的属性被删除。
2、枚举
因为 JavaScript 的数组其实就是对象,所以 for in
语句可以用来遍历一个数组的全部属性。然而 for in
无法保证属性的顺序。此外,还有可能从原型链中得到意外的属性错误。
因此,推荐使用常规的 for
循环语句可以有效避免这些问题。
3、判断数组和对象
1 | // 不同浏览器兼容性不好 |
第七章 正则表达式
1、结构
有两种方法来创建一个 RegExp
对象。优先考虑正则表达式字面量方法。
1 | var my_regexp = /^([0-9]{0-3})$/; |