JavaScript包含了少量可用在标准类型上的标准方法。
Array
array.concat(item…)
concat方法返回一个新数组,它包含array的浅复制(shallow copy)并将1个或多个参数item附加在其后。如果参数item是一个数组,那么它的每个元素会被分别添加。此外,请参见本章后面的array.push(item…)方法。
var a=[‘a’,’b’,’c’];
var b=[‘x’,’y’,’z’];
var ca.concat(b,true);
//c是[‘a’,’b’,’c’, ‘x’,’y’,’z’,true]
array.join(separator)
join方法把一个array构造成一个字符串。它将array中的每个元素构造成一个字符串,并用一个separator为分隔符把它们连接在一起。默认的separator是’,’。为了实现无间隔的连接,我们可以使用空字符串作为separator。
如果你想把大量的片段组装成一个字符串,把这些片段放到一个数组中并用join方法连接它们通常比用+运算符连接这些片段要快。
var a=['a','b','c'];
a.push('d');
var c=a.join(''); //c是'abcd'
array.pop()
pop和push方法使数组array像堆栈(stack)一样工作。pop方法移除array中的最后一个元素并返回该元素。如果该array是空的,它会返回undefined。
var a=['a','b','c'];
var c=a.pop(); //a是['a','b'],c是'c'
array.push(item…)
push方法将一个或多个参数item附加到一个数组的尾部。不像concat方法那样,它会修改该数组array,如果参数item是一个数组,它会将参数数组作为单个元素整个添加到数组中。它返回这个数组array的新长度值。
var a=['a','b','c'];
var b=['x','y','z'];
var c=a.push(b,true);
array.reverse()
reverse方法反转array中的元素的顺序。它返回当前的array:
var a=['a','b','c'];
var b=a.reverse();
//a和b都是['c','b','a']
array.shift()
shift方法移除数组array中的第一个元素并返回该元素。如果这个数组array是空的,它会返回undefined。shift通常比pop慢得多。
var a=['a','b','c'];
var c=a.shift(); //a是['b','c']c是'a'
array.slice(start,end)
slice方法对array中的一段做浅复制。第一个被复制的元素是array[start](含array[start])。它将一直复制到array[end](不含array[end])为止。end参数是可选的,并且默认值是该数组的长度array.length。如果两个参数中的任何一个是负数,array.length将和它们相加来试图使它们成为非负数。如果start大于等于array.length,得到的结果将是一个新的空数组。千万别把slice和splice混淆了。此外请参见本章后面的string.slice。
var a=['a','b','c'];
var b=a.slice(0,1); //b是['a']
var c=a.slice(1); //c是['b','c']
var d=a.slice(1,2); //d是['b']
array.sort(comparefn)
sort方法对array中的内容进行适当的排序。它不能正确地给一组数字排序:
var n=[4,8,15,16,23,42];
n.sort();
//n是[15,16,23,4,42,8]
JavaScript的默认比较函数假定所要被排序的元素都是字符串。它尚未足够智能到在比较这些元素之前先检测它们的类型,所以当它比较这些的时候会将它们转化为字符串,从而导致一个令人吃惊的错误结果。
不过,你可以对其进行改进。你可以自己写一个如何完成两数比较的函数来替换掉默认的比较函数。这个比较函数应该接受两个参数,如果这两个参数相等则返回0,如果第一个参数应该排在前面,则返回负数,如果第二个参数应该排在前面,则返回正数。
n.sort(function(a,b){return a-b;});//默然说话:所传的参数,就是自定义的比较函数
上面这个函数将给数字排序,但它不能给字符串排序。如果我们想要给任何简单值数组排序,则必须做更多的工作:
var m=['aa','bb','a',4,8,15,16,23,42];
m.sort(function (a,b){
if(a===b){
return 0;
}
if(typeof a ===typeof b){
return a<b?-1:1;
}
return typeof a < typeof b ? -1:1;
});//m是[4,8,15,16,23,42,’a’,’aa’,’bb’]
如果大小写不重要,你的比较函数应该在比较运算数之前先将它们转化为小写。此外请参见本章后面的string.localeCompare。
//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
};
}
};
};
var s=[
{first:'Joe',last:'Besser'},
{first:'Moe',last:'Howard'},
{first:'Joe',last:'Derita'},
{first:'Shemp',last:'Howard'},
{first:'Larry',last:'Fine'},
{first:'Curly',last:'Howard'}
];
s.sort(by('first'));
//s是[
//{first:'Curly',last:'Howard'},
//{first:'Joe',last:'Derita'},
//{first:'Joe',last:'Besser'},
//{first:'Larry',last:'Fine'},
//{first:'Moe',last:'Howard'},
//{first:'Shemp',last:'Howard'}
//]
array.splice(start,deleteCount,item…)
splice方法从array中移除1个或多个元素,并用新的item替换它们。参数start是从数组array中移除元素的开始位置。参数deleteCount是要移除的元素个数。如果有额外的参数,那些item都将插入到所移除元素的位置上。它返回一个包含被移除元素的数组。
var a=['a','b','c'];
var r=a.splice(1,1,'ache','bug');
//a是['a','ache','bug','c']
//r是['b']
array.unshift(item…)
unshift方法像push方法一样用于将元素添加到数组中,但它是把item插入到array的开始部分而不是尾部。它返回array的新的长度值:
var a=['a','b','c'];
var r=a.unshift('?','@');
//a是['?','@','a','b','c']
//r是5
Function
function.apply(thisArg,argArray)
apply方法调用函数function,传递一个将被绑定到this上的对象和一个可选的参数数组。apply方法被用在apply调用模式中(参见第4章)。
Function.method('bind',function(that){
//返回一个函数,调用这个函数就像它是那个对象的方法一样。
var method=this,
slice=Array.prototype.slice,
args=slice.apply(arguments,[1]);
return function(){
return method.apply(that,args.concat(slice.apply(arguments,[0])));
};
});
var x=function(){
return this.value;
}.bind({value:666});
alert(x());//666
Number
number.toExponential(fractionDigits)
toExponential方法把这个number转换成一个指数形式的字符串。可选参数fractionDigits控制其小数点后的数字位数。它的值必须在0至20之间。
document.writeln(Math.PI.toExponential(0)+'<br />');
document.writeln(Math.PI.toExponential(2)+'<br />');
document.writeln(Math.PI.toExponential(7)+'<br />');
document.writeln(Math.PI.toExponential(16)+'<br />');//默然说话:其实Math.PI只精确到小数点后15位
document.writeln(Math.PI.toExponential()+'<br />');
number.toFixed(fractionDigits)
toFixed方法把这个number转换成为一个十进制数形式的字符串。可选参数fractionDigits控制其小数点后的数字位数。它的值必须在0和20之间。默认为0:
document.writeln(Math.PI.toFixed(0)+'<br />');
document.writeln(Math.PI.toFixed(2)+'<br />');
document.writeln(Math.PI.toFixed(7)+'<br />');
document.writeln(Math.PI.toFixed(16)+'<br />');
document.writeln(Math.PI.toFixed()+'<br />');
number.toPrecision(precision)
toPrecision方法把这个number转换成为一个十进制数形式的字符串。可选参数precision控制有效数字的位数。它的值必须在1和21之间:(默然说话:原书有误,经实际测试,应该为1到21之间)
document.writeln(Math.PI.toPrecision(1)+'<br />');
document.writeln(Math.PI.toPrecision(2)+'<br />');
document.writeln(Math.PI.toPrecision(7)+'<br />');
document.writeln(Math.PI.toPrecision(16)+'<br />');
document.writeln(Math.PI.toPrecision()+'<br />');
number.toString(radix)
toString方法把这个number转换成为一个字符串。可选参数radix控制基数。它的值必须在2和36之间。默认的radix是以10为基数的。radix参数最常用的是整数,但是它可以用任意的数字。(默然说话:换个说法,radix这个参数就是表示按几进制来转换这个数字,2表示二进制,以此类推。)
Object
object.hasOwnProperty(name)
如果这个object包含了一个名为name的属性,那么hasOwnProperty方法返回true。原型链中的同名属性是不会被检查的。这个方法对name就是hasOwnProperty时不起作用,此时会返回false:
var a={member:true};
var b=Object.beget(a);//beget来自第3章
var t=a.hasOwnProperty('member');
var u=b.hasOwnProperty('member');
var v=b.member;
RegExp
regexp.exec(string)
exec方法是使用正则表达式的最强大(和最慢)的方法。如果它成功地匹配regexp和字符串string,它会返回一个数组。数组中下标为0的元素将包含正则表达式regexp匹配的子字符串。下标为1的元素是分组1捕获的文本,下标为2的元素是分组2捕获的文本。如果匹配失败,那么它会返回null。
如果regexp带有一个g标志(全局标志),事情变得更加复杂了。查找不是从这个字符串的起始位置开始,而是从regexp.lastIndex(它初始化为0)位置开始。如果匹配成功,那么regexp.lastIndex将被设置为该匹配后第一个字符的位置。不成功的匹配会重置regexp.lastIndex为0。
这就允许你通过在一个循环中调用exec去查询一个匹配模式在一个字符串中发生几次。有两件事情需要注意。如果你提前退出了这个循环,再次进入这个循环前必须把regexp.lastIndex重置到0。^因子也仅匹配regexp.lastIndex为0的情况。
//把一个简单的HTML文本分解为标签和文本。
//(entityify方法请参见string.replace)
//对每个标签和文本,都产生一个数组包含如下元素
//[0]整个匹配的标签和文本
//[1]/(斜杠),如果有的话
//[2]标签名
//[3]属性,如果有任何属性的话
//默然说话:这个方法将在后面的内容中详细说明
String.method('entityify',function(){
var character={
'<':'<',
'>':'>',
'&':'&',
'"':'"'
};
//返回string.entityify方法,它返回调用替换方法的结果
//它的replaceValue函数返回在一个对象中查找一个字符的结果
//这种对象的用法通常优于switch语句
return function(){
return this.replace(/[<>&"]/g,function(c){
return character[c];
});
};
}());
var text='<html><body bgcolor=linen><p>'+
'This is <b>bold<//b>!<//p><//body><//html>';
var tags=/[^<>]+|<(//?)([A-Za-z]+)([^<>]*)>/g;
var a,i;
while((a=tags.exec(text))){
for(i=0;i<a.length;i+=1){
document.writeln(('//['+i+'] '+a[i]).entityify()+'<br />');
}
document.writeln('<br />');
}
regexp.test(string)
test方法是使用正则表达式的最简单(和最快)的方法。如果该regexp匹配string,它返回true,否则,它返回false。不要对这个方法使用g标识:
var b=/&.+;/.test('frank & beans');
//b是true
String
string.charAt(pos)
charAt方法返回在string中pos位置处的字符。如果pos小于0或大于等于字符串的长度string.length,它会返回空字符串。由于JavaScript没有字符这种数据类型。这个方法返回的结果是一个字符串。
var name=’Curly’;
var initial=name.charAt(0); //initial是’C’
string.charCodeAt(pos)
charCodeAt方法同charAt一样,只不过它返回的不是一个字符串,而是以整数形式表示的在string中的pos位置处的字符的ASCII码。
var name=’Curly’;
var initial=name.charCodeAt(0); //initial是67
string.concat(string…)
concat方法通过将其他的字符串连接在一起来构造一个新的字符串。它很少被使用,因为+运算符更为方便:
var s=’C’.concat(‘a’,’t’); //s是’Cat’
string.indexOf(searchString,position)
indexOf方法在string内查找另一个字符串searchString。如果它被找到,则返回第一个匹配字符的位置,否则返回-1.可选参数position可设置从string的某个指定的位置开始查找:
var text=’Mississippi’;
var p=text.indexOf(‘ss’); //p是2
p=text.indexOf(‘ss’,3); //p是5
p=text.indexOf(‘ss’,6); //p是-1
stirng.lastIndexOf(searchString,position)
lastIndexOf方法和indexOf方法类似,只不过它是从该字符串的末尾开始查找而不是从开头:
var text=’Mississippi’;
var p=text.lastIndexOf(‘ss’); //p是5
p=text. lastIndexOf(‘ss’,3); //p是2
p=text. lastIndexOf(‘ss’,6); //p是5
string.localeCompare(that)
localeCompare方法比较两个字符串。如何比较字符串的规则没有详细的说明。如果string比字符串that小,那么结果为负数。如果它们是相等的,那么结果为0.这类似于array.sort比较函数的约定:
var m=['AAA','A','aa','a','Aa','aaa'];
m.sort(function(a,b){
return a.localeCompare(b);
});
alert(m);
//默然说话:IE下面是[a,A,aa,Aa,aaa,AAA],而谷歌浏览器是[A,AAA,Aa,a,aa,aaa],火狐的与IE一致,苹果的是[A,a,Aa,aa,AAA,aaa],Opera与谷歌的一致
string.match(regexp)
match方法匹配一个字符串和一个正则表达式。它依据g标识来决定如何进行匹配。如果没有g标识,那么调用string.match(regexp)的结果与调用regexp.exec(string)的结果相同。然而,如果regexp带有g标识,那么它返回一个包含除捕获分组之外的所有匹配的数组:
var text='<html><body bgcolor=linen><p>'+
'This is <b>bold<//b>!<//p><//html>';
var tags=/[^<>]+|<(//?)([A-Za-z]+)([^<>]*)>/g;
var a,i;
a=text.match(tags);
for(i=0;i<a.length;i+=1){
document.writeln('<br />'+('//['+i+']'+a[i]).entityify());
}
string.replace(searchValue,replaceValue)
replace方法对string进行查找和替换的操作,并返回一个新的字符串。参数searchValue可以是一个字符串或一个正则表达式对象。如果它是一个字符串,那么searchValue只会在第一次出现的地方被替换,所以下面的代码结果是”mother-in_law”:
var result="mother_in_law".replace('_','-');
这或许令你失望。
如果searchvalue是一个正则表达式并且带有g标志,那么它将替换所有匹配之处。如果它没有带g标志,那么它将仅替换第一个匹配之处。
replaceValue可以是一个字符串或一个函数。如果replaceValue是一个字符串,字符$拥有特别的含义:
var oldareacode=//((/d{3})/)/g;
var p='(555)666-1212'.replace(oldareacode,'$1-');
美元符号序列 | 替换对象 |
$$ | $ |
$& | 整个匹配的文本 |
$number | 分组捕获的文本 |
$` | 匹配之前的文本 |
$’ | 区配之后的文本 |
如果replaceValue是一个函数,此方法将对每个匹配依次调用它,并且该函数返回的字符串将被用作替换文本。传递给这个函数的第一个参数是整个被匹配的文本。第二个参数是分组1捕获的文本,下一个参数是分组2捕获的文本,依此类推:
String.method('entityify',function(){
var character={
'<':'<',
'>':'>',
'&':'&',
'"':'"'
};
//返回string.entityify方法,它返回调用替换方法的结果
//它的replaceValue函数返回在一个对象中查找一个字符的结果
//这种对象的用法通常优于switch语句
return function(){
return this.replace(/[<>&"]/g,function(c){
return character[c];
});
};
}());
alert(“<&>”.entityify());
string.search(regexp)
search方法和indexOf方法类似,只是它接受一个正则表达式对象作为参数而不是一个字符串。如果找到匹配,它返回第一个匹配的首字符位置,如果没有找到匹配,则返回-1.此方法会忽略g标志,且没有position参数:
var text='and in it he says "Any damn fool could';
var pos=text.search(/["']/);//pos是18
string.slice(start,end)
slice方法复制string的一部分来构造一个新的字符串。如果start参数是负数,它将与string.length相加。end参数是可选的,并且它的默认值是string.length。如果end参数是负数,那么它将与string.length相加。end参数是一个比最末一个字符的位置值还大的数。要想得到从位置p开始的n个字符,就用 string.slice(p,p+n)。此外,请参见分别在本章前面和后面介绍的string.substring和array.slice。
string.split(separator,limit)
split方法把这个string分割成片段来创建一个字符串数组。可选参数limit可以限制被分割的片段数量。separator参数可以是一个字符串或一个正则表达式。
如果separator是一个空字符串,将返回一个单字符的数组:
var digits='0123456789';
var a=digits.split('',5);
//a是['0','1','2','3','456789']
//默然说话:经IE,Opera,谷歌,firefox测试,a的值是['1','2','3','4']
否则,此方法会在string中查找所有separetor出现的地方。分隔符两边的每个单元文本都会被复制到该数组中。此方法会忽略g标志:
var ip='192.168.1.0';
var b=ip.split('.');
alert(b);
var c='|a|b|c|'.split('|');
alert(c);
var text='last, first ,middle';
var d=text.split(//s*,/s*/);
alert(d);
有一些特例须特别注意。来自分组捕获的文本将会被包含在被分割后的数组中:
var e=text.split(//s*(,)/s*/);
alert(e);//e是[‘last’,’,’,’first’,’,’,middle’]
当separator是一个正则表达式时,有一些JavaScript的实现在输出数组中会禁止空字符串:
var c='|a|b|c|'.split('//|/');
alert(c);
//默然说话:很奇怪,这个程序在我所有的浏览器都得不到答案,似乎那个正则表达式是错误的,因为它并没有返回一个数组,而是直接返回了这个字符串。
string.substring(start,end)
substring的用法和slice方法一样,只是它不能处理负数参数。没有任何理由去使用substring方法,请用slice替代它。
string.toLocaleLowerCase()
toLocaleLowerCase方法返回一个新字符串,它使用本地化的规则把这个string中的所有字母转换为小写格式。这个方法主要是用在土耳其语上,因为在土耳其语中’I’转换为’I’,而不是’I’。
string.toLocaleUpperCase()
toLocaleUpperCase方法返回一个新字符串,它使用本地化的规则把这个string中的所有字母转换为大写格式。这个方法主要是用在土耳其语上,因为在土耳其语中’I’转换为’I’,而不是’I’。
string.toLowerCase()
toLowerCase方法返回一个新的字符串,这个string中的所有字母都被转化为小写格式。
string.toUpperCase()
toUpperCase方法返回一个新的字符串,这个string中的所有字母都被转化为大写格式。
String.fromCharCode(char…)
String.fromCharCode函数从一串数字中返回一个字符串。
var a=String.fromCharCode(67,97,116);
//a是'Cat'