欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ECMAScript 6 入门——字符串的新增方法

程序员文章站 2022-03-08 22:17:28
...

四、字符串的新增方法

1.String.fromCodePoint()

以下均用于从Unicode码点返回对于字符
(1)ES5的String.fromCharCode()只能返回0x0000-0xFFFF的字符串,不能访问大于0xFFFF的字符
(2)ES6的String.fromCodePoint()则可识别大于0xFFFF的字符,弥补了不足。

(1)
0x20BB7发生溢出最高两位被抛弃,返回码点0+0BB7对应字符
String.fromCharCode(0x20BB7)
// "ஷ"
(2)
String.fromCodePoint(0x20BB7)
// "????"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true

2.String.codePointAt()方法

  • 理论/原由
    JS的内部,字符以UTF-16的格式存储,每个字符固定为两个字节,对于那些需要4个字节存储的字符(Unicode码点大于0xFFFF的字符),JS会认为是两个字符。
  • charAt()无法读取整个字符(返回指定位置的字符)
  • charCodeAt()只能返回前两个字节和后两个字节的值
  • codePointAt()能正确处理4个字节存储的字符,返回一个字符的码点
var s = "????";

s.length // 2
s.charAt(0) // ''
s.charAt(1) // ''
s.charCodeAt(0) // 55362
s.charCodeAt(1) // 57271
  • String.codePointAt()的使用方法
    字符串实例对象,参数是字符串需转码的位置,把字符转成Unicode码点,十进制。
let s = '????a';

s.codePointAt(0) // 134071 //????
s.codePointAt(1) // 57271 //????的后两位字符
s.codePointAt(2) // 97 //a
s.codePointAt(0).toString(16) // "20bb7"
s.codePointAt(2).toString(16) // "61"
  • 解决参数位置不明了问题(上面的a位置实际为1而不是2)
    (1)使用for…of循环
    (2)使用数组存放字符串的各个字符,再用foreach
(1)
let s = '????a';
for (let ch of s) {
  console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
// 61
(2)解构将字符串拆分成数组
let arr = [...'????a']; // arr.length === 2
arr.forEach(
  ch => console.log(ch.codePointAt(0).toString(16))
);
// 20bb7
// 61
  • 如何判断一个字符是2个字节还是4个字节组成
function is32Bit(c) {
  return c.codePointAt(0) > 0xFFFF;
}

is32Bit("????") // true
is32Bit("a") // false
String.codePointAt()与String.fromCodePoint()区别

(1)codePointAt的String是字符串的实例对象
(2)fromCodePoint是String对象的静态方法

const a='abc'
a.codePointAt(0)//实例对象

String.fromCodePoint('a')//静态方法

3.String.raw()

该静态方法对输入的字符串中的斜杠都进行转义(\变\)

String.raw`Hi\n${2+3}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hi\n5!"

String.raw`Hi\u000A!`;
// 实际返回 "Hi\\u000A!",显示的是转义后的结果 "Hi\u000A!"
  • 用处
    专用于模板字符串的标签函数。如写成正常函数的形式,它的第一个参数应该是具有raw属性的对象,且是个数组,对应模板字符串解析后的值
something`foo${1 + 2}bar`
//something函数后的模板字符串=>something([foo,bar],1+2)
//raw属性的值等同于标签函数解析后得到的数组
String.raw({ raw: ['foo', 'bar'] }, 1 + 2) // "foo3bar"

String.raw()实现代码
String.raw = function (strings, ...values) {
  let output = '';
  let index;
  for (index = 0; index < values.length; index++) {
    output += strings.raw[index] + values[index];
  }

  output += strings.raw[index]
  return output;
}

4.实例方法:normalize()

  • 理论/原由
    许多欧洲语言有语调符号和重音符号。为了表示它们,Unicode 提供了两种方法。
    (1)直接提供带重音符号的字符,比如Ǒ(\u01D1)。
    (2)提供合成符号(combining character),即原字符与重音符号的合成,两个字符合成一个字符,比如O(\u004F)和ˇ(\u030C)合成Ǒ(\u004F\u030C)。
    这两种表示方法在视觉和语义上都等价,但JS不能识别!
'\u01D1'==='\u004F\u030C' //false

'\u01D1'.length // 1
'\u004F\u030C'.length // 2
  • normalize()方法
    ES6字符串实例方法,用来将字符的不同表示方法统一为统一的形式,这称为Unicode正规化。
'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

normalize方法可接受一个参数指定normalize的方式,参数有四个可选值:

(1)NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
(2)NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
(3)NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
(4)NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。
'\u004F\u030C'.normalize('NFC').length // 1
'\u004F\u030C'.normalize('NFD').length // 2
缺点是不能识别3个或3个以上字符的合成。这种情况还是只能使用正则表达式,通过Unicode编号区间判断

5.实例方法:includes(),startsWith(),endsWith()

JS原只提供了indexOf方法来确定一个字符串是否包含在另一个字符串中。
ES6又新增了三种新方法(参数2为开始搜索位置):

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';

s.includes('Hello', 6) // false
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true //endsWith的第二个参数则是针对前n个字符

6.实例方法:repeat()

返回一个新字符串,表示原字符串重复n次。
参数说明:
(1)小数则向下取整 2.9=>2
(2)0到-1等于0
(3)非数字字符串等于0 ‘a’=>0
(4)数字字符串会转换为数字 ‘3’=>3
(5)负数报错

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

7.实例方法:padStart(),padEnd()

ES2017引入了字符串补全长度的功能。即某个字符串不够指定长度则会进行补全。

  • padStart用于头部补全
  • padEnd用于尾部补全
    (1)原字符串+补全字符串<=最大长度。自动补全
    (2)原字符串>=最大长度。补全无效,返回原字符串
    (3)原字符串+补全字符串>最大长度。则截去补全字符串超出的部分再进行补全
    (4)省略第二个参数,默认用空格补全
(1)
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
(2)
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'
(3)
'abc'.padStart(10, '0123456789')
// '0123456abc'
(4)
'x'.padStart(4) // '   x'
'x'.padEnd(4) // 'x   '
  • 用途
    1.为数值补全指定位数
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"

2.提示字符串格式

'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

8.实例方法:trimStart(),trimEnd()

ES2019新增trimStart()和trimEnd两个消除空格/换行/tab等不可见空白的方法。都是返回新字符串,不影响原字符串

  • trim()
  • trimStart()
  • trimEnd()
const s = '  abc  ';

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

9.实例方法:matchAll()

返回正则表达式在当前字符串的所有匹配。详见:ECMAScript 6 入门——正则的扩展

相关标签: 前端 ES6