《JavaScript语言精粹》第八章-方法

他虽疯,但却有他的一套理论。
———威廉-莎士比亚

Array

array.concat(item..)
concat方法产生一个新数组,包含一份array数组的浅复制(shallow copy)并把一个或多个参数item附加在其后。如果item是数组,它的每个元素会被分别添加。

array.join(separator)
join方法把一个array构造成一个字符串。它先把array中每一个元素构造成一个字符串,接着用一个separator分隔符把它们连接在一起。默认separator是逗号“,”。

array.pop()array.push(item…)
poppush方法使得数组像堆栈一样工作。
push(item…)如果item是数组,则它会把参数数组作为单个元素整个添加到数组中。

1
2
3
4
5
6
7
8
9
10
//pop可以这样实现
Array.method('pop',function(){
return this.splice(this.length-1,1)[0];
});

//push可以这样实现
Array.method('push',function(){
this.splice.apply(this,[this.length,0].concat(Array.prototype.slice.apply(arguments));
return this.length;
});

array.shift()
shift方法移除数组array中的第一个元素并返回该元素。如果这个数组为空,它会返回undefined。shift通常比pop慢得多。

1
2
3
Array.method('shift',function(){
return this.splice(0,1)[0];
});

array.slice(start,end)
slice方法对array中的一段做浅复制。首先复制array[start],一直复制到array[end]为止。“前包后不包”。end参数可选,默认值是该数组长度。
如果两个参数中的任何一个是负数,array.length会和它们相加,试图让他们成为非负数。
如果start>=array.length,得到的结果将是一个新的空数组。

array.sort(comparefn)
sort方法对array中的内容进行排序,但不能正确的给一组数字排序,因为默认的比较函数会把要被排序的元素视为字符串。
但可以使用自己的比较函数作为参数替代默认比较函数。下面是给任何包含简单值的数组排序:

1
2
3
4
5
6
7
8
9
10
var m=['aa','bb','a',4,8,15,16,23,43];
m.sort(function(){
if(a===b){
return 0;
}
if(typeof a === typeof b){
return a<b ? -1:1;
}
return typeof a < typeof b ? -1:1;
});

我们可以编写一个构造更智能的比较函数的函数,来满足一般情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//by函数接受一个成员名字符串作为参数
//并返回一个可以用来对包含该成员的对象数组进行排序的比较函数
var by=function(name){
return function(o,p){
var a,b;
if(typeof o ==='object'&&typeof p ==='object'&& o &&p){
a=o[name];
b=p[name];
if(a===b){
return 0;
}
if(typeof a === typeof b){
return a < b?-1:1;
}
return typeof a < typeof b?-1:1;
}else{
throw{
name:'Error',
message:'Expected an object when sorting by'+name
};
}
};
};

sort方法是不稳定的,不建议链式调用sort方法。

array.splice(start,deleteCount,item…)
splice方法从array中移除一个或多个元素,并用新的item替换它们。它返回一个包含被移除元素的数组。
参数start代表开始位置,deleteCount代表被移除的元素个数,可以为0,item会插入到被移除元素的位置。
splice可在像这样实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Array.method('splice',function(start,deleteCount){
var max=Math.max,
min=Mathh.min,
delta,
element,
insertCount=max(arguments.length-2,0),
k=0,
len=this.length,
new_len,
result=[],
shift_count;

start=start||0;
//start若为负数,则从数组末位开始计位(从1开始)
if(start<0){
start+=len;
}

//这一条代码兼顾两种特殊情况:
//若start为正,且大于等于数组长度,则从数组末尾开始添加内容
//若start为负,且大于等于数组长度,则从数组第一项开始操作
start=max(min(start,len),0);

//这一条代码兼顾3种特殊情况
//若deleteCount被省略(不是一个数),则其相当于len-start
//若deleteCount为正,且大于等于start之后的元素的总数,则其相当于len-start
//若deleteCount为负,且大于等于start之后的元素的总数,则其等于0
deleteCount=max(min(typeof deleteCount==='number' ? deleteCount : len,len-start),0);
});

//添加的元素数和删除的元素数之差
delta=insertCount-deletCount;
new_len=len+delta;

//给要返回的数组赋值
while(k<deleteCount){
element=this[start+k];
if(element!=undefined){
result[k]=element;
}
k+=1;
}

//start后面不用改变的元素的个数
shift_count=len-start-deleteCount;
//将start后面不用改变的元素赋值给改变后的新数组
if(delta<0){
k=start+insertCount;
while(shift_count){ //从起始点开始逐个替换
this[k]=this[k-delta];
k+=1;
shift_count-=1;
}
this.length=new_len;
}else if(delta>0){ //在新数组长度下从后往前替换
k=1;
while(shift_count){
this[new_len-k]=this[len-k];
k+=1;
shift_count-=1;
}
this.length=new_len;
}

//将添加的元素赋值给数组
for(k=0;k<insertCount;k++){
this[start+k]=arguments[k+2];
}

//返回被删除的元素组成的数组
return result;
});

array.unshift(item…)
unshift把元素添加到数组开始部分。返回array的新length。
可以这样实现:

1
2
3
4
Array.method('unshift',function(){
this.splice.apply(this,[0,0].concat(Array.prototype.slice.apply(arguments)));
return this.length;
});

Number

number.toExponential(fractionDigits)
toExponential方法把这个number转换成一个指数形式的字符串。可选参数控制小数点位数。参数值必须在0-20中。

number.toFixed(fractionDigits)
toFixed方法把这个number转换成十进制数形式的字符串。可选参数控制小数点位数。参数必须在0-20中。

number.toPrecision(precision)
toPrecision方法把这个number转换成十进制数形式的字符串。可选参数控制小数点位数。参数必须在0-21中。

RegExp

regexp.exec(string)
exec方法如果成功的匹配regexp和字符串string,它会返回一个数组。数组下标为0的元素将包含regexp匹配的子字符串。下标为1的元素是分组1捕获的文本,以此类推。
如果regexp带有g标识,会改变regexp.lastIndex的值。

regexp.test(string)
如果regexp匹配string,就返回true,否则返回false。不要对这个方式使用g标识。

String

string.charAt(pos)
可以这样实现:

1
2
3
String.method('string',function(){
return this.slice(pos,pos+1);
});

string.match(regexp)
match方法让字符串和一个正则表达式匹配。它依据g标识来决定如何进行匹配。
如果没有g标识,那么调用string.match(regexp)的结果与调用regexp.exec(string)相同。
如果带有g标识,那么它生产一个包含所有匹配(无捕获分组)的数组。

string.replace(searchValue,replaceValue)
replace方法对string进行查找和替换操作,并返回一个新的字符串。searchValue可以是字符串或正则表达式,replaceValue可以是字符串或函数。
如果replaceValue是字符,字符$有特别的含义。
如果replaceValue是函数,那么每遇到一次匹配,函数就会调用一次,该函数返回的字符串会被用做替换文本。传递给这个函数第1个参数是整个被匹配的文本,第2个参数是分组1捕获的文本,以此来类推。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
String.method('entityify',function(){
var character={
'<':'&lt',
'>':'&gt',
'&':'&amp',
'"':'&quot'
};

return function(){
return this.replace(/[<>&'']/g,function(c){
return character[c];
});
};
}());

console.log('<&>'.entityify());

string.search(regexp)
indexOf类似,但它只接受一个正则表达式对象作为参数。忽略g标识,没有position参数。

string.slice()
array.slice很像,都是复制再截取构造一个新实例。两个参数若为负数,则与length相加,或者从末位往前数(从1计数)。前包后不包。

string.split(separator,limit)
split方法把string分割成片段来创建一个字符串数组。可选参数limit可以限制被分割的片段数量。separator参数可以是字符串或者正则表达式。此方法会忽略g标识。
注意:来自分组捕获的文本会被包含在被分割后的数组中

1
2
3
var text='last,first,middle';
var e=text.split(/\s*(,)\s*/);
//e是['last',',','first',',','middle']
liborn wechat
欢迎您扫一扫上面的微信二维码,订阅我的公众号!