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(ES2015)新特性知识点整理
下一篇: php页面缓存ob系列函数介绍