《JavaScript语言精粹》学习笔记
Author:chemandy
摘录书中一些有用的知识点。
第二章 语法
2.1 空白
JavaScriptt中使用/* */块注释方法可能会于正则表达式发生冲突。建议避免使用/* */而用//代替。
2.2 标识符
JavaScript不允许在对象字面量中,或者在一个属性存取表达式的点号之后,使用保留字作为对象的属性名。
2.4 字符串
字符串是不可变的。一旦字符串被创建,就永远无法改变它。(对字符串的修改实质上是销毁旧字符串再创建新字符串的过程)
2.5 语句
JavaScript中代码块不会创建一个新的作用域,因此变量应该被定义在函数的顶端,而不是代码块中。
第三章 对象
3.1 对象字面量
在对象字面量中,如果属性名是一个合法的JavaScript标识符且不是保留字,并不强制要求用引号括住属性名。所以用引号括住"first-name"是必须的,但是否括住first_name则是可选的。
3.2 检索
尝试检索一个undefined值会导致TypeError异常。这可以通过&&运算符来避免错误。例如:查询是否有c属性,不应该直接查找a.b.c而是a.b&&a.b.c
3.7 枚举
for in语句可用来遍历一个对象中的所有属性名。枚举过程将会列出所有属性——所以有必要过滤掉那些你不想要的值。最为常用的过滤器是hasOwnProperty方法,以及使用typeof来排除函数。
3.8 删除
delete运算符可以用来删除对象属性。它将会移除对象中确定包含的属性。它不会触及原型链中的任何对象。
第四章 函数
4.1 函数对象
①在JavaScript中函数就是对象。函数对象的__proto__连接到Function.prototype(该原型对象的__proto__又连接到了Object.prototype)。
②每个函数在创建时附有两个附加的隐藏属性:函数的上下文和实现函数行为的代码。
③JavaScript创建一个函数对象时,会给该对象设置一个“调用”属性。当JavaScript调用一个函数时,可理解为调用此函数的“调用”属性。
4.3 调用
在JavaScript中一共有四种调用模式:方法调用模式、函数调用模式、构造调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异。
①方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。方法可以使用this去访问对象,所以它能从对象中取值或修改对象。this到对象的绑定发生在调用的时候。这个“超级”迟绑定使得函数可以对this高度复用。通过this可取得它们所属对象的上下文的方法称为公共方法。
②函数调用模式
当函数并非一个对象的属性时,那么它被当做一个函数来调用。此模式下this绑定到全局对象。通过在对象内将this赋值给that,可以使函数模式下调用that来访问指定对象。
③构造器调用模式
如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会绑定到那个新对象上。
④Apply调用模式
apply方法,第一个参数指定this绑定的值。
4.4 参数
因为语言的一个设计错误,arguments并不是一个真正的数组。它只是一个“类似数组(array-like)”的对象。arguments拥有一个length属性,但它缺少所有的数组方法。
4.5 返回
一个函数总是返回一个值。如果没有指定返回值,则返回undefined。如果函数以在前面加上new前缀的方式来调用,且返回值不是一个对象,则返回this(该新对象)。
4.9 作用域
JavaScript不支持块级作用域。所以,最好的做法是在函数体的顶部声明函数中可能用到的所有变量。
4.12 模块
模块是一个提供接口却隐藏状态与实现的函数或对象。
4.13 级联
如果让方法返回this而不是undefined,就可以启用级联。在一个级联镇南关,我们可以单独一条语句中一次调用同一个对象的很多方法。
4.14 套用
套用允许我们将函数与传递给它的参数相结合去产生一个新的函数。
4.15 记忆
函数可以用对象去记住操作的结果,从而能避免无谓的运算。这种优化被称为记忆。JavaScript的对象和数组要实现这种优化是非常方便的。(惰性载入记忆的一种)
第五章 继承
5.1 伪类
当一个函数对象被创建时,Function构造函数产生的函数对象会运行类似这样的一些代码: this.prototype={constructor:this};
第六章 数组
6.7 维度
①JavaScript没有多维数组,但就像大多数类C语言一样,它支持元素为数组的数组:
var matrix = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
matrix[2][1] //7
第十章 优美的特性
1. 函数是头等对象
在精简JavaScript中,函数是有词法作用域的闭包(lambda)。
2. 基于原型继承的动态对象
对象是无类别的。我们可以通过普通的赋值给任何对象增加一个新成员元素。一个对象可以从另一个对象继承成员元素。
3. 对象字面量和数组字面量
这对创建新的对象和数组来说是一种非常方便的方法。
附录A 糟粕
1. 全局变量(程序越大,它们的变得越难处理)
2. 作用域(没有块级作用域)
3. 自动插入分号(可能会掩盖更为严重的错误)
4. 保留字(大多数没有使用,且不能被用来命名变量或参数)
5. Unicode(Unicode把一个字符视为一个单一的字符。而javascript认为一对字符是两个不同的字符)
6. typeof(typeof不能辨别出null与对象,对正则表达式识别上各js实现不一致)
7. parseInt(建议转换时总是提供基数参数)
8. +(可能用于加法运算或字符串连接)
9. 浮点数(0.1 + 0.2 != 0.3)
10. NaN
11. 伪数组(JavaScript没有真正的数组,不需设维度永远不越界,但性能可能比真正的数组糟糕的多)
12. 假值(有一大组假值但互相不能互换)
13. hasOwnProperty(是一个方法而不是运算符)
14. 对象(JavaScript没有真正的空对象)
附录B 鸡肋
1. ==(判断过程会试图强制转换其值的类型)
2. with语句(本意是想用来快捷地访问对象的属性,但严重影响处理速度,因为它阻止了变量名的词法作用域绑定)
3. eval(授予文本过大权力,不安全)
4. continue语句(用于跳到循环的顶部。但发现通过重构移除continue语句后性能得到改善)
5. switch贯穿
6. 缺少块语句
7. ++ --(代码变得过于紧密、复杂和隐晦)
8. 位运算符(Java里,位运算符处理的是整数,JavaScript没有整数类型,需转换。因此非但不是硬件处理,而且非常慢)
9. function语句对比函数表达式
10. 类型的包装对象(永远不要手动实例化包装类型)
11. new(构造函数忘记使用new时,this值绑定到全局变量)
12. void(存在于js里,但没什么用)