概述
ES6 入门教程
ECMAScript 6 入门
作者:阮一峰
本文仅用于学习记录,不存在任何商业用途,如侵删
文章目录
- ES6 入门教程
- 5 字符串的新增方法
- 5.1 String.fromCodePoint()
- 5.2 String.raw()
- 5.3 实例方法:codePointAt()
5 字符串的新增方法
5.1 String.fromCodePoint()
ES5 提供String.fromCharCode()
方法,用于从 Unicode 码点返回对应字符,但是这个方法不能识别码点大于0xFFFF
的字符。
String.fromCharCode(0x20BB7)
// "ஷ"
上面代码中,String.fromCharCode()
不能识别大于0xFFFF
的码点,所以0x20BB7
就发生了溢出,最高位2
被舍弃了,最后返回码点U+0BB7
对应的字符,而不是码点U+20BB7
对应的字符。
ES6 提供了String.fromCodePoint()
方法,可以识别大于0xFFFF
的字符,弥补了String.fromCharCode()
方法的不足。
在作用上,正好与下面的codePointAt()
方法相反。
String.fromCodePoint(0x20BB7)
// "????"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'xuD83DuDE80y'
// true
上面代码中,如果String.fromCodePoint
方法有多个参数,则它们会被合并成一个字符串返回。
注意,fromCodePoint
方法定义在String
对象上,而codePointAt
方法定义在字符串的实例对象上。
5.2 String.raw()
ES6 还为原生的 String 对象,提供了一个raw()
方法。
该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法。
String.raw`Hin${2+3}!`
// 实际返回 "Hi\n5!",显示的是转义后的结果 "Hin5!"
String.raw`Hiu000A!`;
// 实际返回 "Hi\u000A!",显示的是转义后的结果 "Hiu000A!"
如果原字符串的斜杠已经转义,那么String.raw()
会进行再次转义。
String.raw`Hi\n`
// 返回 "Hi\\n"
String.raw`Hi\n` === "Hi\\n" // true
String.raw()
方法可以作为处理模板字符串的基本方法,它会将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用。
String.raw()
本质上是一个正常的函数,只是专用于模板字符串的标签函数。如果写成正常函数的形式,它的第一个参数,应该是一个具有raw
属性的对象,且raw
属性的值应该是一个数组,对应模板字符串解析后的值。
// `foo${1 + 2}bar`
// 等同于
String.raw({ raw: ['foo', 'bar'] }, 1 + 2) // "foo3bar"
上面代码中,String.raw()
方法的第一个参数是一个对象,它的raw
属性等同于原始的模板字符串解析后得到的数组。
作为函数,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;
}
5.3 实例方法:codePointAt()
JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2
个字节。
对于那些需要4
个字节储存的字符(Unicode 码点大于0xFFFF
的字符),JavaScript 会认为它们是两个字符。
var s = "????";
s.length // 2
s.charAt(0) // ''
s.charAt(1) // ''
s.charCodeAt(0) // 55362
s.charCodeAt(1) // 57271
上面代码中,汉字“????”(注意,这个字不是“吉祥”的“吉”)的码点是0x20BB7
,UTF-16 编码为0xD842 0xDFB7
(十进制为55362 57271
),需要4
个字节储存。对于这种4
个字节的字符,JavaScript 不能正确处理,字符串长度会误判为2
,而且charAt()
方法无法读取整个字符,charCodeAt()
方法只能分别返回前两个字节和后两个字节的值。
ES6 提供了codePointAt()
方法,能够正确处理 4 个字节储存的字符,返回一个字符的码点。
let s = '????a';
s.codePointAt(0) // 134071
s.codePointAt(1) // 57271
s.codePointAt(2) // 97
codePointAt()
方法的参数,是字符在字符串中的位置(从 0 开始)。上面代码中,JavaScript 将“????a”视为三个字符,codePointAt 方法在第一个字符上,正确地识别了“????”,返回了它的十进制码点 134071(即十六进制的20BB7
)。在第二个字符(即“????”的后两个字节)和第三个字符“a”上,codePointAt()
方法的结果与charCodeAt()
方法相同。
总之,codePointAt()
方法会正确返回 32 位的 UTF-16 字符的码点。
对于那些两个字节储存的常规字符,它的返回结果与charCodeAt()
方法相同。
codePointAt()
方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString()
方法转换一下。
let s = '????a';
s.codePointAt(0).toString(16) // "20bb7"
s.codePointAt(2).toString(16) // "61"
可以看到,codePointAt()
方法的参数,仍然是不正确的。比如,上面代码中,字符a
在字符串s
的正确位置序号应该是 1,但是必须向codePointAt()
方法传入 2。
解决这个问题的一个办法是使用for...of
循环,因为它会正确识别 32 位的 UTF-16 字符。
let s = '????a';
for (let ch of s) {
console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
// 61
另一种方法也可以,使用扩展运算符(...
)进行展开运算。
let arr = [...'????a']; // arr.length === 2
arr.forEach(
ch => console.log(ch.codePointAt(0).toString(16))
);
// 20bb7
// 61
codePointAt()
方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。
function is32Bit(c) {
return c.codePointAt(0) > 0xFFFF;
}
is32Bit("????") // true
is32Bit("a") // false
最后
以上就是潇洒项链为你收集整理的ES6 入门教程 5 字符串的新增方法 5.1 String.fromCodePoint() & 5.2 String.raw() & 5.3 实例方法:codePointAt()的全部内容,希望文章能够帮你解决ES6 入门教程 5 字符串的新增方法 5.1 String.fromCodePoint() & 5.2 String.raw() & 5.3 实例方法:codePointAt()所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复