js string类
2.8.4 String类
String类是String原始类型的对象表示法,它是以下列方式创建的:
String对象的valueOf()方法和toString()方法都会返回String型的原始值:
如果运行这段代码,输出是"true",说明这些值真的相等。
String类是ECMAScript中的比较复杂的引用类型之一。同样,本节的重点只是String类的基本功能。更多的高级功能将分别在本书适合的主题中进行介绍。
String类具有属性length,它是字符串中的字符个数:
这个例子输出的是"11",即"hello world"中的字符个数。注意,即使字符串包含双字节的字符(与ASCII字符相对,ASCII字符只占用一个字节),每个字符也只算一个字符。
String类还有大量的方法。首先,两个方法charAt()和charCodeAt()访问的是字符串中的单个字符。在2.6.6节中介绍过,第一个字符的位置是0,第二个字符的位置是1,依此类推。这两个方法都有一个参数,即要操作的字符的位置。charAt()方法返回的是包含指定位置处的字符的字符串:
在字符串"hello world"中,位置1处的字符是"e",因此调用charAt(1)返回的是"e"。如果想得到的不是字符,而是字符代码,那么可以调用charCodeAt():
这个例子输出"101",即小写字母"e"的字符代码。
接下来是concat()方法,用于把一个或多个字符串连接到String对象的原始值上。该方法返回的是String原始值,保持原始的String对象不变:
在上面这段代码中,调用concat()方法返回的是"hello world",而String对象存放的仍然是"hello"。出于这种原因,较常见的是用加号(+)连接字符串,因为这种形式从逻辑上表明了真正的行为:
迄今为止,已讨论过连接字符串的方法,访问字符串中的单个字符的方法。不过如果无法确定在某个字符串中是否确实存在一个字符,应该调用什么方法呢?这时,可调用indexOf()和lastIndexOf()方法。
indexOf()和lastIndexOf()方法返回的都是指定的子串在另一个字符串中的位置(或-1,如果没找到这个子串)。这两个方法的不同之处在于,indexOf()方法是从字符串的开头(位置0)开始检索子串,而lastIndexOf()则是从字符串的结尾开始检索子串的。例如:
这里,第一个"o"字符串出现在位置4,即"hello"中的"o";最后一个"o"字符串出现在位置7,即"world"中的"o"。如果该字符串中只有一个"o"字符串,那么indexOf()和lastIndexOf()方法返回的位置相同。
下一个方法是localeCompare(),对字符串值进行排序。该方法有一个参数——要进行比较的字符串,返回的是下列3个值之一:
q 如果String对象按照字母顺序排在参数中的字符串之前,返回负数(最常见的是-1,不过真正返回的值是由实现决定的)。
q 如果String对象等于参数中的字符串,返回0。
q 如果String对象按照字母顺序排在参数中的字符串之后,返回正数(最常见的是1,不过同样,真正返回的值是由实现决定的)。
示例如下:
在这段代码中,字符串"yellow"与3个值进行了对比,即"brick"、"yellow"和"zoo"。由于按照字母顺序排列,"yellow"位于"brick"之后,所以localCompare()返回1;"yellow"等于"yellow",所以localCompare()返回0;"zoo"位于"yellow"之后,localCompare()返回-1。再强调一次,由于返回的值是由实现决定的,所以最好以下面的方式调用localCompare():
采用这种结构,可以确保这段代码在所有实现中都能正确运行。
localCompare()的独特之处在于,实现所处的区域(locale,兼指国家/地区和语言)确切说明了这种方法运行的方式。在美国,英语是ECMAScript实现的标准语言,localCompare()是区分大小写的,大写字母在字母顺序上排在小写字母之后。不过,在其他区域情况可能并非如此。
ECMAScript提供了两种方法从子串创建字符串值,即slice()和substring()。这两种方法返回的都是要处理的字符串的子串,都接受一个或两个参数。第一个参数是要获取的子串的起始位置,第二个参数(如果使用的话)是要获取子串终止前的位置(也就是说,获取终止位置处的字符不包括在返回的值内)。如果省略第二个参数,终止位就默认为字符串的长度。与concat()方法一样,slice()和substring()方法都不改变String对象自身的值。它们只返回原始的String值,保持String对象不变。
在这个例子中,slice()和substring()方法的用法相同,返回的值也一样。当只有参数3时,两个方法返回的都是"lo world",因为"hello"中的第二个"l"位于位置3上。当有两个参数3和7时,两个方法返回的都是"lo w"("world"中的字母"o"位于位置7上,所以它不包括在结果中)。为什么有两个功能完全相同的方法呢?事实上,这两个方法并不完全相同,不过只在参数为负数时,它们处理参数的方式才稍有不同。
对于负数参数,slice()方法会用字符串的长度加上参数,substring()方法则将其作为0处理(也就是说将忽略它)。例如:
这样即可看出slice()和substring()方法的主要不同。当只有参数-3时,slice()返回"rld",substring()则返回"hello world"。这是因为对于字符串"hello world",slice(-3)将被转换成slice(8),而substring(-3)则被转换成substring(0)。同样,使用参数3和-4时,差别也很明显。slice()方法将被转换成slice(3,7),与前面的例子相同,返回"lo w"。而substring()方法则将这两个参数解释为substring(3,0),实际上即substring(0,3),因为substring()总是把较小的数字作为起始位,较大的数字作为终止位。因此,substring(3,-4)返回的是"hel"。这里的最后一行代码用来说明如何使用这些方法。
最后一套要讨论的方法涉及大小写转换。有4种方法用于执行大小写转换,即toLower- Case()、toLocaleLowerCase()、toUpperCase()和toLocaleUpperCase()。从名字上可以看出它们的用途,前两种方法用于把字符串转换成全小写的,后两种方法用于把字符串转换成全大写的。toLowerCase()和toUpperCase()方法是原始的,是以java.lang.String中的相同方法为原型实现的。toLocaleLowerCase()和toLocaleUpperCase()方法是基于特定的区域实现的(与localeCompare()的用法相同)。在许多区域中,区域特定的方法都与通用的方法完全相同。不过,有几种语言对Unicode大小写转换应用了特定的规则(例如土耳其语),因此必须使用区域特定的方法才能进行正确的转换。
这段代码中,toUpperCase()和toLocaleUpperCase()方法输出的都是"HELLO WORLD",toLowerCase()和toLocaleLowerCase()方法输出的都是"hello world"。一般说来,如果不知道在以哪种编码运行一种语言,则使用区域特定的方法比较安全。
记住,String类的所有属性和方法都可应用于String原始值上,因为它们是伪对象。