二刷《JavaScript语言精粹》,做些笔记在这里。
看过有些对这本书有些非议的说法,我想主要是这本书讨论的是 ES5 的原因吧,毕竟第一版出版距现在已经有7年时间之久了。
而如今我们更多时候是在讨论 ES6,MVVM 框架和虚拟 DOM,构建工具等等。
但有一点可以肯定,目前我们还是避不开 ES5 的。
第2章 语法
NaN 不等于任何值,包括它自己。
我们使用isNaN(number)
来检测 NaN。当 var 语句用在函数内部时,它定义这个函数的私有变量。
ES5 中代码块不会创建新的作用域,因此变量应该被定义在函数的头部,而不是代码块中。
for in
会枚举一个对象的所有属性名或键名,通常配合object.hasOwnProperty()
来检查属性名是该对象的成员,还是来自原型链。
for(vari in obj){
if(obj.hasOwnProperty(vari)){
...
}
}
return 语句会导致函数中提前返回。也可以指定要被返回的值。
如果没有指定返回表达式,那么返回值是 undefined。typeof
运算符产生的值有number, string, boolean, undefined, function 和 object
。
如果运算数是一个数组或 null,那么结果是object
,这其实是不对的。
第3章 对象
JavaScript 的简单数据类型包括 string,number,boolean,undefined,null 。其它所有的值都别看作是对象。
string,number 和 boolean 貌似对象,因为它们拥有方法,但它们的值可以改变。对象是属性的容器。
如果尝试检索一个不存在的属性,将返回 undefined。
对象的值可以通过赋值语句来更新。如果属性名存在,那么属性值就会被替换:
obj.silence = "hush hush"
如果对象之前没有这个属性名,那么该属性就被扩充到对象中。当我们对某个对象改动时,不会触及该对象的原型。
如果我们尝试获取某个属性值,但该对象没有此属性,那么 JavaScript 会试着从原型对象中获取属性值。
如果原型对象也没有改属性值,那么再从它的原型中寻找以此类推,直到该过程最后到达终点 Object.prototype。原型关系是动态的。如果我们添加一个属性到原型中,该属性会立即对所有基于该原型创建的对象可见。
第4章 函数
函数用于指定对象的行为。
函数可以保存在变量,对象和数组中。
函数可以被当做参数传递给其它函数,函数也可以再返回函数。
而且,因为函数是对象,所以函数可以拥有方法。函数对象可以通过函数字面量形式来创建:
var foo = function(a, b){
return a + b;
}
函数分4个部分:
第1部分是关键字 function。
第2部分是函数名,它是可以被省略的。函数可以用它的名字来递归调用自己。如果没有给函数命名,比如上面例子,那么这个函数被称为"匿名函数"。
第3部分是参数。第4部分是函数主体。
函数也可以被定义在其它函数中。
一个函数内部的函数除了可以访问自己的参数和变量,同时也能自由访问把他嵌套在其中的父函数的参数和变量。
通过函数字面量创建的函数对象包含一个连接到外部上下文的链接。这被称为闭包。如果实际参数值过多,超出的参数值会被忽略。
如果实际参数值过少,缺失的值会被替换为undefined
。
对参数值不会进行类型检查,任何类型的值都可以传递给参数。-
除了声明时定义的形式参数,每函数还接受两个附加的参数:
this
和arguments
。
参数 this 在面向对象中非常重要,它的值取决于调用模式。总共有4中调用模式:方法调用模式,函数调用模式,构造器调用模式和 apply 调用模式。- 方法调用模式:
当一个函数被保存为对象的一个属性时,我们称它为一个方法。
当一个方法被调用时,this
被绑定到该对象。
方法可以使用var obj = { val: 0, increase: function(){ this.val++ } } obj.increase(); //方法调用
this
访问自己所属的对象,从中取值或对对象进行修改。
通过 this 可取得它们所属对象的上下文的方法称为公共方法。 - 函数调用模式:
当一个函数并非一个对象的属性时,即是函数调用。
var sum = add(3, 4); //函数调用
此时,this 被绑定到全局对象。 - 构造器调用模式:
// 创建一个名为 Person 的构造器函数。 var Person = function(param){ this.name = param; getName: function(){ return this.name; } } var pitt = new Person('Brade Piit'); // 构造一个实例 console.log(pitt.getName()); // 打印 "Brade Pitt"
- 方法调用模式:
一个函数创建目的就是希望结合new 前缀来调用,那么它就被称为构造器函数。
* Apply(Call / Bind) 调用模式
apply 方法允许我们构建一个参数数组传递给函数。允许我们选择 this 值。
apply 方法接受两个参数,第一个是要绑定给 this 的值,第二个就是一个参数数组。
var arr = [3, 4];
var sum = add.apply(null, arr);
* 定义在函数中的参数和变量在函数外部是不可见的。而在函数内部任何地方都可见。
* 最好的做法是在函数体内顶部定义所有需要的变量。
* 作用域的好处是内部函数可以访问外部函数的参数和变量(this 和 arguments 除外)。
***
### 第8章 方法
* Array
* `array.concat(item)`
concat 方法产生一个新数组,它包含一份 array 的前复制并把若干个参数 item 附加在其后。
var a = [1, 2, 3];
var b = [4, 5, 6];
var c = a.concat(b, 7);
// c 变成 [1, 2, 3, 4, 5, 6, 7]
* `array.join(separator)`
join 方法把一个 array 构造成一个 string,它把 array 中的每个元素构造成一个字符串接着用 separator 分隔符把它们连接在一起。
var arr = ['a', 'b', 'c'];
var str = arr.join(',');
// str 为 "a,b,c"
* `array.push(item)`
push 方法把一个或多个参数 item 附加到一个数组的尾部。
var a = [1, 2, 3];
var b = 'x';
var c = a.push(b);
// c 为 [1, 2, 3, x]
* `array.pop()`
pop 方法与 push 正相反,它将一个数组中的最后一个元素移除。
* `array.unshift(item)`
unshift 方法和 push 方法类似,将参数填充的数组中,不同的是,它将参数填充到数组头部。
var a = [1, 2, 3];
var b = a.unshift(0);
// b 为 [0, 1, 2, 3]
* `array.shift()`
shift 方法与 unshift 正相反,它将数组头部的元素移除。
* `array.slice(start, end)`
slice 方法对 array 中的一段做浅复制。
var a = [1, 2, 3, 4];
var b = a.slice(2, 1);
// b 为 [3]
* `array.splice(start, deleteCount, item)`
splice 方法从 array 中移除一个或多个元素,并用新的 item 替换它们。
var a = [1, 2, 3, 4, 5];
var b = a.splice(1, 3, 'a');
// b 为 [1, a, 5]
* Number
* `number.toFixed(fractionDigital)`
toFixed 方法把数字转换成一个十进制数字。可选参数 fractionDigital 控制其小数点后的位数。
```
var PI = 3.1415926
PI.toFixed(2) // 3.14
PI.toFixed(10) // 3.1415926000
```
* `number.toPrecision(precision)`
toPrecision 方法把数字转换成一个十进制数字。可选参数与 toFixed 方法略有不同,它控制的是整个数字的有效位数。
```
PI.toPrecision(2); // 3.1
PI.toPrecision(10); // 3.14159265300
```
* `number.toString()`
toString 方法把数字转换成一个字符串。
* RegExp
* `regexp.test(string)`
test 方法匹配 string,则返回 true。
不要对整个方法使用全局匹配(不使用 g 标识)。
* String
* `string.charAt(position)`
charAt 方法返回字符串中 position 位置的字符。
如果 position 小于0或大于字符串长度,则返回空字符串。
```
var str = 'Curry'
var initial = str.charAt(0) // 'C'
```
* `string.indexOf(searchString, position)`
indexOf 方法用来检测字符串中是否含有搜索的字符串 searchString,如果是则返回第一个匹配字符的位置,如果否则返回-1。
可选参数 position 可设置从 string 的某个位置开始查找。
```
var name = 'Jack Sparrow'
name.indexOf('ac') // 1
name.indexOf('pa', 5) // 1
```
* `string.lastIndexOf(searchString, postion)`
与 indexOf 方法类似,只是从字符串的尾部开始查找。
* `string.slice(start, end)`
slice 方法浅复制 string 的一部分来构造一个新的字符串。
* `string.split(separator, limit)`
split 方法把字符串分割成片段来创建一个数组。
可选参数 limit 控制最多分割的片段数量。
如果 separator 是空字符,则返回单字符数组。
```
var digi = `1234567890`
var arr = digi.split('', 5) // ['1', '2', '3', '4', '567890']
```
* `string.toLowerCase()`
toLowerCase 返回一个新的字符串。string 中所有字符被转换成小写字符。
* `string.toUpperCase()`
toUpperCase 返回一个新的字符串。string 中所有字符被转换成大写字符。
*[完]*