这篇博客继续分享高程四第五章的内容。
3. 字符串操作方法
本节介绍几个操作字符串值的方法。首先是 concat() ,用于将一个或多个字符串拼接成一个新字符串。来看下面的例子:
let stringValue = "hello ";
let result = stringValue.concat("world");
console.log(result); // "hello world"
console.log(stringValue); // "hello"
在这个例子中,对 stringValue 调用 concat() 方法的结果是得到 "hello world" ,但 stringValue 的值保持不变。concat() 方法可以接收任意多个参数,因此可以一次性拼接多个字符串,如下所示:
let stringValue = "hello ";
let result = stringValue.concat("world", "!");
console.log(result); // "hello world!"
console.log(stringValue); // "hello"
这个修改后的例子将字符串 "world" 和 "!" 追加到了 "hello" 后面。虽然 concat() 方法可以拼接字符串,但更常用的方式是使用加号操作符( + )。而且多数情况下,对于拼接多个字符串来说,使用加号更方便。
ECMAScript提供了3个从字符串中提取子字符串的方法:slice() 、 substr() 和 substring() 。这3个方法都返回调用它们的字符串的一个子字符串,而且都接收一或两个参数。第一个参数表示子字符串开始的位置,第二个参数表示子字符串结束的位置。对slice() 和 substring() 而言,第二个参数是提取结束的位置(即该位置之前的字符会被提取出来)。对 substr() 而言,第二个参数表示返回的子字符串数量。任何情况下,省略第二个参数都意味着提取到字符
let stringValue = "hello world";
console.log(stringValue.slice(-3)); // "rld"
console.log(stringValue.substring(-3)); // "hello world"
console.log(stringValue.substr(-3)); // "rld"
console.log(stringValue.slice(3, -4)); // "lo w"
console.log(stringValue.substring(3, -4)); // "hel"
console.log(stringValue.substr(3, -4)); // "" (empty string)
串末尾。与 concat() 方法一样, slice() 、substr() 和 substring() 也不会修改调用它们的字符串,而只会返回提取到的原始新字符串值。来看下面的例子:
let stringValue = "hello world";
console.log(stringValue.slice(3)); // "lo world"
console.log(stringValue.substring(3)); // "lo world"
console.log(stringValue.substr(3)); // "lo world"
console.log(stringValue.slice(3, 7)); // "lo w"
console.log(stringValue.substring(3,7)); // "lo w"
console.log(stringValue.substr(3, 7)); // "lo worl"
在这个例子中, slice() 、 substr() 和 substring() 是以相同方式被调用的,而且多数情况下返回的值也相同。如果只传一个参数3 ,则所有方法都将返回 "lo world" ,因为 "hello" 中 "l" 位
置为3。如果传入两个参数 3 和 7 ,则 slice() 和 substring()返回 "lo w" (因为 "world" 中 "o" 在位置7,不包含),而substr() 返回 "lo worl" ,因为第二个参数对它而言表示返回的字符数。
当某个参数是负值时,这3个方法的行为又有不同。比如, slice()方法将所有负值参数都当成字符串长度加上负参数值。而 substr() 方法将第一个负参数值当成字符串长度加上该值,将第二个负参数值转换为0。 substring() 方法会将所有负参数值都转换为0。看下面的例子:
let stringValue = "hello world";
console.log(stringValue.slice(-3)); // "rld"
console.log(stringValue.substring(-3)); // "hello world"
console.log(stringValue.substr(-3)); // "rld"
console.log(stringValue.slice(3, -4)); // "lo w"
console.log(stringValue.substring(3, -4)); // "hel"
console.log(stringValue.substr(3, -4)); // "" (empty string)
这个例子明确演示了3个方法的差异。在给 slice() 和 substr() 传入负参数时,它们的返回结果相同。(它们把“-1”当成是“倒数第一的位置”)这是因为 -3 会被转换为 8 (长度加上负参数),实际上调用的是 slice(8) 和 substr(8) 。而substring() 方法返回整个字符串,因为 -3 会转换为 0 。在第二个参数是负值时,这3个方法各不相同。 slice() 方法将第二个参数转换为 7 (第二个参数也当成了“倒数第几”),实际上相当于调用 slice(3, 7) ,因此返回 "lo w" 。而 substring() 方法会将第二个参数转换为 0 ,相当于调用substring(3, 0) ,等价于 substring(0, 3) ,这是因为这个方法会将较小的参数作为起点,将较大的参数作为终点。对substr() 来说,第二个参数会被转换为 0 ,意味着返回的字符串包含零个字符,因而会返回一个空字符串。(substring遇到参数为负值的时候,把负值变成0以后还会倒过来取,substr不会倒过来)
4. 字符串位置方法
有两个方法用于在字符串中定位子字符串: indexOf() 和lastIndexOf() 。这两个方法从字符串中搜索传入的字符串,并返回位置(如果没找到,则返回 -1 )。两者的区别在于,indexOf() 方法从字符串开头开始查找子字符串,而lastIndexOf() 方法从字符串末尾开始查找子字符串。来看下面的例子:
let stringValue = "hello world";
console.log(stringValue.indexOf("o")); // 4
console.log(stringValue.lastIndexOf("o")); // 7
这里,字符串中第一个 "o" 的位置是4,即 "hello" 中的 "o" 。最后一个 "o" 的位置是7,即 "world" 中的 "o" 。如果字符串中只有一个 "o" ,则 indexOf() 和 lastIndexOf() 返回同一个位置。
这两个方法都可以接收可选的第二个参数,表示开始搜索的位置。这意味着, indexOf() 会从这个参数指定的位置开始向字符串末尾搜索,忽略该位置之前的字符; lastIndexOf() 则会从这个参数指定的位置开始向字符串开头搜索,忽略该位置之后直到字符串末尾的字符。下面看一个例子:
let stringValue = "hello world";
console.log(stringValue.indexOf("o", 6)); //7
console.log(stringValue.lastIndexOf("o", 6)); //4
在传入第二个参数 6 以后,结果跟前面的例子恰好相反。这一次,indexOf() 返回 7 ,因为它从位置6(字符 "w" )开始向后搜索字符串,在位置7找到了 "o" 。而 lastIndexOf() 返回 4 ,因为它从位置6开始反向搜索至字符串开头,因此找到了 "hello" 中的 "o" 。像这样使用第二个参数并循环调用 indexOf() 或lastIndexOf() ,就可以在字符串中找到所有的目标子字符串,如下所示:
let stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
let positions = new Array();
let pos = stringValue.indexOf("e");
while(pos > -1) {positions.push(pos);pos = stringValue.indexOf("e", pos + 1);
}
console.log(positions); // [3,24,32,35,52]
这个例子逐步增大开始搜索的位置,通过 indexOf() 遍历了整个字符串。首先取得第一个 "e" 的位置,然后进入循环,将上一次的位置加1再传给 indexOf() ,确保搜索到最后一个子字符串实例之后。每个位置都保存在 positions 数组中,可供以后使用。
5. 字符串包含方法
ECMAScript 6增加了3个用于判断字符串中是否包含另一个字符串的方法: startsWith() 、 endsWith() 和 includes() 。这些方法都会从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值。它们的区别在于, startsWith() 检查开始于索引0的匹配项,endsWith() 检查开始于索引 (string.length -substring.length) 的匹配项,而 includes() 检查整个字符串:
let message = "foobarbaz";
console.log(message.startsWith("foo")); // true
console.log(message.startsWith("bar")); // false
console.log(message.endsWith("baz")); // true
console.log(message.endsWith("bar")); // false
console.log(message.includes("bar")); // true
console.log(message.includes("qux")); // false
startsWith() 和 includes() 方法接收可选的第二个参数,表示开始搜索的位置。如果传入第二个参数,则意味着这两个方法会从指定位置向着字符串末尾搜索,忽略该位置之前的所有字符。下面是一个例子:
let message = "foobarbaz";
console.log(message.startsWith("foo")); // true
console.log(message.startsWith("foo", 1)); // false
console.log(message.includes("bar")); // true
console.log(message.includes("bar", 4)); // false
endsWith() 方法接收可选的第二个参数,表示应该当作字符串末尾的位置。如果不提供这个参数,那么默认就是字符串长度。如果提供这个参数,那么就好像字符串只有那么多字符一样:
let message = "foobarbaz";
console.log(message.endsWith("bar")); // false
console.log(message.endsWith("bar", 6)); // true
6. trim() 方法
ECMAScript在所有字符串上都提供了 trim() 方法。这个方法会创建字符串的一个副本,删除前、后所有空格符,再返回结果。比如:
let stringValue = " hello world ";
let trimmedStringValue = stringValue.trim();
console.log(stringValue); // " hello world "
console.log(trimmedStringValue); // "hello world"
由于 trim() 返回的是字符串的副本,因此原始字符串不受影响,即原本的前、后空格符都会保留。另外, trimeLeft() 和 trimRight() 方法分别用于从字符串开始和末尾清理空格符。
7. repeat() 方法
ECMAScript在所有字符串上都提供了 repeat() 方法。这个方法接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果。
let stringValue = "na ";
console.log(stringValue.repeat(16) + "batman");
// na na na na na na na na na na na na na na na na batman
8. padStart() 和 padEnd() 方法
padStart() 和 padEnd() 方法会复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件。这两个方法的第一个参数是长度,第二个参数是可选的填充字符串,默认为空格(U+0020)。
let stringValue = "foo";
console.log(stringValue.padStart(6)); // " foo"
console.log(stringValue.padStart(9, ".")); // "......foo"
console.log(stringValue.padEnd(6)); //"foo "
console.log(stringValue.padEnd(9, ".")); // "foo......"