JS笔记《字符串扩展》

47 阅读1分钟

Unicode表示法

  • 允许采用\uxxxx形式表示一个字符,其中xxxx字符表示Unicode码点。但是这种表示法只限于码点在\u0000~\uFFFF之间的字符。超出这个范围的字符,必须写在{}中。
console.log("\u0061");   // 'a'

console.log('\uD842\uDFB7'); // 𠮷 ES5的写法
console.log("\u{20BB7}");    // 𠮷 ES6的改进,只要将码点放入大括号就能正确解读
'\u{20BB7}' === '\uD842\uDFB7'  // true

遍历器接口

  • ES6为字符串添加了遍历器(Iterator)接口,使得字符可以被for..of循环遍历。
for (let codePoint of 'foo') {
  console.log(codePoint)
}
// "f"
// "o"
// "o"
  • 遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别。
let text = String.fromCodePoint(0x20BB7);

for (let i = 0; i < text.length; i++) {
  console.log(text[i]);
}
// " "
// " " 双字节

for (let i of text) {
  console.log(i);
}
// "𠮷"

模板字符串

  • 大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
// 普通字符串
`In JavaScript '\n' is a line-feed.`

// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`  // 'Hello Bob, how are you today?'

// 使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中
let ul = `
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`

新增方法

静态方法

fromCodePoint()

  • ES5 提供String.fromCharCode()方法,用于从 Unicode 码点返回对应字符,但是这个方法不能识别码点大于0xFFFF的字符。ES6 提供了String.fromCodePoint()方法,可以识别大于0xFFFF的字符。
String.fromCodePoint(0x20BB7)  // "𠮷"

String.fromCodePoint(0x78, 0x1f680, 0x79) //  'x🚀y' 多个参数会被合并成一个字符串

raw()

  • 该方法返回一个斜杠都被转义的字符串,往往用于模板字符串的处理方法。
String.raw`Hi\n${2+3}!` // 'Hi\\n5!'

实例方法

codePointAt()

  • 会正确返回四个字节的UTF-16字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt()方法相同。
let s = "𠮷";

s.length        // 2  因为超出了 \u0000~\uFFFF 码点,会用两个码点(4个字节)表示,所以长度为2
s.charAt(0)     // '' 无法读取
s.charAt(1)     // '' 无法读取
s.charCodeAt(0) // 55362 返回的是前两个字节的十进制码点
s.charCodeAt(1) // 57271 返回的是后两个字节的十进制码点

s.codePointAt(0) // 134071 返回的是前两个字节的十进制码点(正确的)
s.codePointAt(1) // 57271  虽然上一个返回的是正确的,但 𠮷 依然是两个码点保存的,后两个字节的十进制码点和charCodeAt相同

// 问题:
let s = '𠮷a';
s.codePointAt(0).toString(16) // "20bb7"
s.codePointAt(2).toString(16) // "61" a在字符串中的正确序号应该是1,但是必须传2。因为 𠮷 的长度是2
// for of正确识别 32 位的 UTF-16 字符
for (let ch of s) {
  console.log(ch.codePointAt(0).toString(16)); // 20bb7  61
}

normalize()

  • 没看懂。

includes()

  • 返回布尔值,表示是否找到了参数字符串。第二个参数,表示开始搜索的位置。
let s = 'Hello world!';
s.includes('o')        // true 
s.includes('Hello', 6) // false

startsWith()

  • 返回布尔值,表示参数字符串是否在原字符串的头部。第二个参数,表示开始搜索的位置。
let s = 'Hello world!';
s.startsWith('H')        // true 
s.startsWith('world', 6) // true

endsWith()

  • 返回布尔值,表示参数字符串是否在原字符串的尾部。第二个参数,表示结束搜索的位置,针对的是前n个字符(指的是前n个字符,是否以指定参数结尾)。
let s = 'Hello world!';
s.endsWith('world!')    // true 
s.endsWith('llo', 5)    // true 

repeat()

  • 返回一个新字符串,表示将原字符串重复n次。
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

// 字符串参数会被转为数字
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"

padStart()

  • 如果某个字符串不够指定长度,会在头部补全。接受两个参数,参数一是字符串补全生效的最大长度;参数二是用来补全的字符串。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

// 常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串
'1'.padStart(10, '0') // "0000000001"

padEnd()

  • 如果某个字符串不够指定长度,会在尾部补全。接受两个参数,参数一是字符串补全生效的最大长度;参数二是用来补全的字符串。
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

trimStart()

  • 消除字符串头部的空格。返回新的字符串。
const s = '  abc  ';

s.trim()      // "abc"
s.trimStart() // "abc  "

trimEnd()

  • 消除字符串头部的空格。返回新的字符串。
const s = '  abc  ';

s.trim()      // "abc"
s.trimStart() // "  abc"

matchAll()

  • 返回一个正则表达式在当前字符串的所有匹配。

replaceAll()

  • 字符串的实例方法replace()只能替换第一个匹配,replaceAll()方法,可以一次性替换所有匹配。
'aabbcc'.replaceAll('b', '_')  // 'aa__cc'
  • 如果参数一是一个不带有g修饰符的正则表达式,replaceAll()会报错。这一点跟replace()不同。
// 不报错
'aabbcc'.replace(/b/, '_')  // 'aa_bcc'

// 报错
'aabbcc'.replaceAll(/b/, '_') // TypeError: String.prototype.replaceAll called with a non-global RegExp argument
  • 参数二是一个字符串,表示替换的文本,其中可以使用一些特殊字符串。
// $& 表示匹配的字符串,即`b`本身
// 所以返回结果与原字符串一致
'abbc'.replaceAll('b', '$&')
// 'abbc'

// $` 表示匹配结果之前的字符串
// 对于第一个`b`,$` 指代`a`
// 对于第二个`b`,$` 指代`ab`
'abbc'.replaceAll('b', '$`')
// 'aaabc'

// $' 表示匹配结果之后的字符串
// 对于第一个`b`,$' 指代`bc`
// 对于第二个`b`,$' 指代`c`
'abbc'.replaceAll('b', `$'`)
// 'abccc'

// $1 表示正则表达式的第一个组匹配,指代`ab`
// $2 表示正则表达式的第二个组匹配,指代`bc`
'abbc'.replaceAll(/(ab)(bc)/g, '$2$1')
// 'bcab'

// $$ 指代 $
'abc'.replaceAll('b', '$$')
// 'a$c'
  • 参数二也可以是一个函数,该函数的返回值会替换掉第一个参数匹配的文本。
'aabbcc'.replaceAll('b', () => '_')   // 'aa__cc'

at()

  • 接受一个整数作为参数,返回参数指定位置的字符,支持负索引。
const str = 'hello';
str.at(1) // "e"
str.at(-1) // "o"