字符串操作方法:slice()、substr()和substring()
ECMAScript提供了3个从字符串中提取子字符串的方法:slice()、substr() 和 substring()。
这3个方法都返回调用它们的字符串的一个子字符串,而且都接收一个或两个参数。
第一个参数表示子字符串开始的位置,第二个参数表示子字符串结束的位置。
对 slice() 和 substring() 而言,第二个参数是提取结束的位置(即该位置之前的字符会被提取出来)。
对 substr() 而言,第二个参数表示返回的子字符串数量。
任何情况下,省略第二个参数都意味着提取到字符串末尾。
与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"; //长度为11
console.log(stringValue.slice(-3)); // "rld" 相当于调用函数stringValue.slice(8) 8 = -3 + 11
console.log(stringValue.substring(-3)); // "hello world" 相当于调用函数stringValue.substring(0)
console.log(stringValue.substr(-3)); // "rld" 相当于调用函数stringValue.substr(8)
console.log(stringValue.slice(3,-4)); // "lo w" 相当于调用函数stringValue.slice(3,7) 7 = -4 + 11
console.log(stringValue.substring(3,-4)); // "hel" 相当于调用函数stringValue.substring(3,0)等价于stringValue.substring(0,3),这个方法会将较小的参数作为起点,将较大的参数作为终点
console.log(stringValue.substr(3,-4)); // ""(empty string) 相当于调用函数stringValue.substr(3,0)
字符串位置方法:indexOf()和lastIndexOf()
有两个方法用于在字符串中定位子字符串: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数组中,可供以后使用。
搜索方法:indexOf()、lastIndexOf()和includes()
indexOf()、lastIndexOf()和includes()还是3个严格相等的搜索方法。
前两个方法在所有 版本中都可以用,而第三个方法是ECMAScript7新增的。
这些方法都接收两个参数:要查找的元素和一个可选的起始搜索位置。indexOf()和includes()方法从数组前头(第一项)开始向后搜索,而lastIndexOf()从数组末尾(最后一项)开始向前搜索。
indexOf()和lastIndexOf()都返回要查找的元素在数组中的位置,如果没找到则返回-1。
includes()返回布尔值,表示是否至少找到一个与指定元素匹配的项。
在比较第一个参数跟数组每一项时,会使用(===)比较,也就是说两项必须严格相等。下面来看一些例子:
let numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.includes(4)); //true
alert(numbers.indexOf(4,4)); //5
alert(numbers.lastIndexOf(4,4)); //3
alert(numbers.includes(4,7)); //false
let person = {name: "Nicholas"};
let people = [{name: "Nicholas"}];
let morePeople = [person];
alert(people.indexOf(person)); //-1
alert(morePeople.indexOf(person)); //0
alert(people.includes(person)); //false
alert(morePeople.includes(person)); //true
trim()、repeat()和concat()方法
trim()方法
ECMAScript在所有字符串上都提供了 trim() 方法。这个方法会创建字符串的一个副本,删除前后所有空格符,再返回结果。比如:
let stringValue = " hello world ";
let trimmedStringValue = stringValue.trim();
console.log(stringValue); //" hello world "
console.log(trimmedStringValue ); //"hello world"
由于trim()返回的是字符串的副本,因此原始字符串不受影响,即原本的前后空格符都会保留。另外,trimLeft()和trimRight()方法分别用于从字符串开始和末尾清理空格符。
repeat()方法
ECMAScript在所有字符串上都提供了repeat()方法。这个方法接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果。
let stringValue = "na ";
console.log(stringValue.repeat(6) + "batman"); // na na na na na na batman
concat()方法
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 "
PS:但是多数情况下,对于拼接多个字符串来说,使用加号更方便。
find()方法
find() 用于找出第一个符合条件的数组元素。它的参数是一个回调函数,所有数组元素依次执行该回调函数,直到找出第一个返回值为true的元素,然后返回该元素。如果没有符合条件的元素,则返回undefined。能接收三个参数,分别为当前元素,当前元素下标以及该数组。
const res = [1, 3, -5, 6].find((item) => item < 0)
// res = -5
const res = [1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
})
// res = 10
findIndex()方法
findIndex() 和find()的使用方法相似,但是返回值不再是满足条件的元素,而是满足条件的元素的下标,当不存在满足条件的元素时,则返回 -1。
const res = [1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
})
// res = 2
此外 find() 和 findInde() 方法都可以发现NaN,弥补了数组的 indexOf 方法的不足。
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(item => Object.is(NaN, item))
// 0