一、字符串基础
字符串是类数组对象,可以通过索引访问、有length属性,但不能改变字符串内的单个字符,用 + 可以连接多个字符串。因为 html 属性值使用双引号,建议字符串使用单引号。
let str = 'hello' + ' ' + 'world';
1. String 和 toString 的区别
String 可以将任意类型的值转为字符串。 toString 原来是 Object 上定义的方法,之后 Array、Number 做继承后又重新定义了自己的 toString,覆盖了 Object 上的。像 null、undefiend 等类型上没有定义 toString 方法,所以调用时会出错。
- String():将参数转为字符串,
null -> 'null',undefined -> 'undefined'。 - a.toString():需要看 a 的类型,该类型是否定义了该 toString 实例方法,以及返回的应该是什么含义的字符串。例如:
Object.prototype.toString:返回一个对象的类型字符串。Array.prototype.toString:返回数组的字符串形式,并且会拉成一维字符串'1, 2, 3',String函数也会。Number.prototype.toString:将数值转为字符串形式。
String(5); // '5'
二、字符串的实例方法
1. ES5 的实例方法
1. charCodeAt
charCodeAt 返回字符串指定位置字符的 Unicode码点(十进制表示),越界则返回 NaN。
'abc'.charCodeAt(0) // 97
2. concat
连接多个字符串,返回一个新的字符串,不改变原字符串,用+更加方便。
let s1 = 'hello', s2 = 'world';
let str = s1.concat(s2);
str // 'helloworld'
3. slice 和 substr:提取子串
slice 和 substr 都是从 原字符串取出子串并返回该子串,不改变原字符串。
str.slice(start, end); // 不包括 end 位置
str.substr(start, length);
// slice
'JavaScript'.slice(4) // 'Script' 只有 1 个参数,则表示一直到字符串结束
'JavaScript'.slice(0, -6) // 'Java' 负值表示倒数
'JavaScript'.substr(4) // 'Script' 同 slice
4. split:字符串 --> 数组
按照给定规则分割字符串,返回一个数组。参数如果为空字符,则返回每个字符;如果为空,则返回一个字符串。
'a|b|c'.split('|') // ['a', 'b', 'c']
'a|b|c'.split('') // ['a', '|', 'b', '|', 'c']
'a|b|c'.split() // ['a|b|c']
5. indexOf / lastIndexOf
正数(倒数)查找一个字符串在另一个字符串中第一次出现的位置,能找到就返回位置,找不到就返回 -1。第 2 个参数(可选)表示从该位置向后(前)匹配。
注意:JS 是区分大小写的!
'hello'.indexOf('ll') // 2
'hello'.indexOf('Hello') // -1
6. toLowerCase / toUpperCase
返回新的字符串,不改变原字符串。
'Hello World'.toLowerCase() // "hello world"
'Hello World'.toUpperCase() // "HELLO WORLD"
7. trim
去除两端的空格,返回一个新的字符串,不改变原字符串。
' hello world '.trim() // 'hello world'
8. match/search/replace/split:用于正则表达式
2. ES6 新增实例方法
1. includes
和 indexOf一样,都是在一个字符串中查找另一个字符串,区别在于 返回值是布尔值,表示是否找到了参数字符串,第 2 个参数表示开始搜索的位置。
'hello'.includes('o');
2. repeat
repeat() 返回一个字符串,表示将原字符串重复 n 次。
'nice'.repeat(2); // 'nicenice'
'hello'.repeat(0); // ''
'hello'.repeat(2.9); //'hellohello' ,参数的小数的话会取整
- 参数是小数,则取整;是
NaN,则相当于 0。 - 参数是 负数 或
Infinity,会报错。
3. ES6 模板字符串
模板字符串是增强版的字符串,用反引号标识。它可以当作普通字符串,也可以用来定义多行字符串,或者在字符串中嵌入变量。
- 所有的空格、缩进都会保留。
- 需要嵌入变量时,将变量名写在
${}中。 - 大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
`In JavaScript this is
not legal.`
`User ${user.name} is not authorized to do ${action}.`
`${x} + ${y} = ${x + y}`
三、字符串总结
- 字符串的所有实例方法都不会改变原字符串(因为字符串不能改变单个字符)。
- concat、slice、substr、toLowerCase、toUpperCase、trim、repeat 都会返回新的字符串。
- indexOf 返回位置索引,找不到则
-1。charCodeAt 返回Unicode 码点(十进制表示),越界则NaN。includes 返回布尔值。 - JS 是区分大小写的。
四、ES5 数组的静态和实例方法
算法题常用到的知识点:初始化二维数组的方法
1. 静态方法 Array.isArray()
Array.isArray 判断参数是否为数组,返回布尔值。可以弥补 typeof 的不足。
2. 实例方法
1. push / pop / shift / unshift:会改变原数组。
-
push: 数组末端添加一个或多个元素,返回新数组的长度。
-
pop:删除数组的最后一个元素,返回该元素。
-
shift:删除数组的第一个元素,返回该元素。
-
unshift:在数组的第一个位置添加一个或多个元素,返回新数组的长度。
2. concat / slice / indexOf / lastIndexOf:字符串也有,不改变原数组
(1)concat 同字符串,而且参数可以是对象、数组或其他值,不改变原数组。
[1, 2].concat([3, 4]); // 新数组 [1, 2, 3, 4]
[1, 2].push([3, 4]); // [1, 2, [3, 4]]
注意:当数组成员中含有对象,那么使用concat()会返回当前数组的一个浅拷贝!
let newArray = objArray.concat()
(2)slice 同字符串,如果没有参数,则返回的是原数组的拷贝。
[1, 2, 3].slice() // [1, 2, 3]
重要应用是,可以转换类数组Array.prototype.slice.call()。
(3)indexOf 同字符串,另外注意 indexOf 不能用来搜索 NaN,因为内部使用的是严格相等运算符, NaN 不等于自身(相等或严格相等都不满足)。
3. splice:改变原数组
用于删除原数组的一部分成员,并且可以在删除的位置添加新的成员,返回值是被删除的元素/数组。
arr.splice(start, length, add1, add2, ...) // 和 slice的第 2 个参数不同
可以插入元素:第 2 个参数设置为0。
arr.splice(start, 0, add1, add2,...)
可以拆分成两个数组:只提供一个参数。
let a = arr.splice(start); // 拆分出的两个数组就是 a 和 arr
4. sort:改变原数组
默认按照字典序排列,也就是 101 < 11。所以使用时务必要传参!
ES2019 规定,sort 排序的算法必须是稳定的。
a.sort((a, b) => a - b); // 升序
a.sort((a, b) => b - a); // 降序
详见 sort的内部算法。
5. join
将数组成员连接成一个字符串并返回,并且字符串之间用给定参数作分隔符。 参数为空时默认用逗号分隔。
- join('') 和 split(''):常用的转换方式。
- join() 和 split():字符串之间用逗号分隔。数组成员只有唯一的一个字符串。
注意:一般都是用空字符。
const arr = ['a', 'b', 'c'];
arr.join(''); // 'abc'
arr.join(); // 'a, b, c'
6. reverse:改变原数组
颠倒数组,返回改变后的数组,会改变原数组。
7. map / forEach / filter / reduce / reduceRight:不改变原数组
详细可见 手写源码。
- map、filter:返回一个数组。
- reduce:返回累计值。
- forEach:没有返回值。
「push四件套、splice、sort、reverse 都改变原数组。」
8. some、every 断言
传参和 map一样,返回的是布尔值。
- some:只要一个成员的返回值是 true,那么就返回 true。
- every:所有成员的返回值都是 true,才返回 true。
五、ES6 数组的静态和实例方法
1. 扩展运算符...
将数组转换为一个用逗号分隔的参数序列,可用于:
- 求最值
Math.max(...arr) // ...后跟数组
2. Array.from
用于将 伪数组转为真正的数组。
3. fill
使用给定值,填充一个数组。第二个、第三个参数用于指定 填充的开始和结束位置,不包括结束位置。
一般来说,编程思想遵循 左闭右开 的准则,因此结束位置的元素不会被包含。
new Array(3).fill(7) // [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
4. find / findIndex
find 找到符合条件的元素并返回,找不到返回undefined。
findIndex类似 indexOf,找到符合条件的元素索引,找不到也会返回 -1。
注意:与 indexOf 不同,find 和 findIndex 可以找到 NaN。
5. flat
6. includes
同ES6的 字符串新增方法。