最近在阅读《Javascript:权威指南,第六版》,这本书给人的感觉就是厚,是个大块头,要啃完这本书,要花很大的功夫不可。
比如,刚看就弄得晕头转向的。
如大家所知,字符串操作在很多编程语言中都是一个重要的内容。就如在Javascript中提取一个子串都有三种方法,你说,为什么就要弄这么多种方法呢?
第一种:string.substr()
substr()在众多语言中,都有这个方法。
String.substr(start, length)
其中:start为子串的开始位置;length为子串的字符数。
其它属性我们先不看,直接上例子:
>>> var str = 'Hello, world!'; str.substr(1,3);
"ell"
这个例子很简单,提取从第一个字符开始(字符串的索引是从0开始的),长度为3的子串。
>>> var str = 'Hello, world!'; str.substr(-5,3);
"orl"
在上面的例子中使用了负数,即起始位置为-5,这的意思就是提取从倒数第5个字符开始,长度为3的子串。这说明在substr()中是可以使用负数作为参数的。
>>> var str = 'Hello, world!'; str.substr(-5);
"orld!"
这说明length参数是可选的,如果不提供此参数,则返回从起始位置到字符串结束的所有的字符。
接下来看一个在IE(这里测试的是IE9)下,结果又将如何:
>> var str = 'Hello, world!'; str.substr(-5);
"Hello, world!"
我们看到,在IE9下,负数的参数将无效,这是在IE下的一个bug。
值得注意的是,在书上说到,此方法在ECMAScript标准中已经被弃用了。
第二种:string.substring()
其实这个方法与上面的方法在写法上很像,就是多一个ing和少一个ing,这很让人混淆,难道是“提取子串ing”,卡死了?!
String.substring(from, to)
其中:from为非负整数,表示子串的第一个字符在string中的位置;to也为非负整数,比要提取的子串的最后一个字符的位置大1(让人头大),此参数是可选参数。
>>> var str = 'Hello, world!'; str.substring(1, 3);
"el"
这个意思很明白。注意:子串的长度为to-from(有很大的用处吗?),即为2,这说明子串中不包含第3个字符。
>>> var str = 'Hello, world!'; str.substring(3, 1);
"el"
我们惊奇的发现,这个例子得出的结果和上面的一样!这个在书上有说明:如果from比to大,这个方法将
先交换两个参数的值
,然后返回它们之间的子串。
为什么要这样设计呢?这就相当于C/C++和PHP的区别一样,一个是严格类型语言,一个是弱类型语言。你能说明白哪个更好,哪个更不好吗?
>>> var str = 'Hello, world!'; str.substring(1, 1);
""
如果from等于to,则返回空子串,因为子串不包含第to个字符。
在上面已经说明,此方法不接受负参数。如果使用了负参数呢?
>>> var str = 'Hello, world!'; str.substring(-1, 3);
"Hel"
>>> var str = 'Hello, world!'; str.substring(-1, -3);
""
到这里,我们发现,其实这两种方法的目的是一样的,都是提取子串。但在处理时的细节上,有些不同:
- 参数不一样,substr()是start和length,substring()是from和to,一个是指定长度,一个是指定结束位置。其实它们之间也是可以通过计算得出的。
- 一个可以使用负数作为参数,另一个则不能。这在特殊情况下是有用的(有待测试)。
- substr()的两个参数如果互换,将得出完全不一样的结果(当然有特殊情况)。而substring()的两个参数(参数要合法)如果互换,将得出一样的结果。
因为在众多语言中,都有substr()方法,其目的也都是一样,提取子串。这里再讲一下在PHP中substr()的用法。
string substr(string string, int start[, int length]);
在PHP中,用法和在Javascript中是一样的,这里就讲一点:在PHP中length也是可以为负数的。
<?php
$str = 'Hello, world!';
echo substr($str, 1, -3);
?>
输出:ello, wor
意思是从第一个字符开始,到倒数第3个字符(不包含倒数第三个字符)。
由于在ECMAScript标准中已经弃用了substr()方法,可能在将来substr()将不能使用,因为substring()又不能使用负数参数,那如果在要使用负数参数的情况下呢?下面将第三种方法。
第三种:string.slice()
String.slice(start, end)
其中:start为子串开始的索引,如果为负,则将从该字符串的尾部开始计算;end为子串结尾的索引(可选参数),如果不指定,则到字符串结尾,如果为负数,则将从该字符串的尾部开始计算。
原理是:一个新的字符串,内容为string中自start位置开始并且包含start位置,直到但不包含end位置的所有字符。
如果参数都为整数,则结果与substring()一样。
>>> var str = 'Hello, world!'; str.slice(-5, -2);
"orl"
这个slice()方法与在PHP中的substr()方法基本一样(PHP中使用length参数,Javascript中的slice()使用end参数),都可以使用负数参数,并且end(PHP中为length)也可以使用负数,当end(PHP中为length)为负数时,将从字符串尾部开始计算。如上例所示,起始位置为-5,即为从倒数第5个字符(包含倒数第5个字符)开始计算,到倒数第2个字符(不包含倒数第2个字符)。
最后,要注意,书目说到,在IE4中,如果start为负数将出现错误,后期版本将没有这个问题,不过IE4早就不用了。
综上:
这三种方法,各有区别,但目的都是一样的。在我们选择的时候,要根据实现的具体细节来选择使用哪个方法。