字符串 String.fromCodePoint和String.raw

678 阅读3分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

前言

ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等

我们一起来ES6字符串的两个静态方法:

  • String.fromCodePoint
  • String.raw

String.fromCodePoint

根据输入的Unicode码点返回对应字符。

String.fromCodePoint(0x61, 0x20034) // 'a𠀴'

ES5其实有一个极其类似的方法, String.fromCharCode, 不过并不能识别码点大于0xFFFF(十进制:65535)码点。

String.fromCharCode(0x61, 0x20034) // 'a4'

当然这是不正确的,String.fromCharCode识别码点大于0xFFFFF的时,是直接去掉高位。 所以上面的方等于:

String.fromCharCode(0x61, 0x0034) // 'a4'
String.fromCharCode(0x61, 0x20034) == String.fromCharCode(0x61, 0x0034) // true

当然,我们还有更加简洁的初始化方法:

var text =  "\u0061\u{20034}" 
console.log(text);  // 'a𠀴'

这里需要额外注意一下,就是码点大于 0xFFFF的字符时,格式是 \u{xxxxx}, 有大括弧。 小于0xFFFF的就可有可无了。

'\u{20034}'  // '𠀴'
'\u{0061}'   // 'a'
'\u0061'     // 'a'

与String.fromCharCode对应的方式,是 String.prototype.codePointAt, 一个是静态方法,一个是原型上的方法,即实例方法。

var text = String.fromCodePoint(0x61, 0x20034) ;
text.length // 3
text[0] //  'a'
text[1] //  '\uD840'
text[2] //  '\uDC34'

text.codePointAt(0);  // 'a' 
text.codePointAt(1);  // '𠀴'

至于text[0], text[1]的输出是这样, 可以参见字符串的遍历

String.raw

获取一个模板字符串的原始字符串的,比如说,占位符(例如 ${foo})会被处理为它所代表的其他字符串,而转义字符(例如 \n)不会。

语法有两种:

String.raw(callSite, ...substitutions)
String.raw`templateString`

先看一个简单MDNString.raw的例子:

`Hi\n${2+3}!`            // 'Hi\n5!'
String.raw`Hi\n${2+3}!`  // 'Hi\n5!'

String.raw `Hi\u000A!`   // 'Hi\u000A!'
`Hi\u000A!`              // 'Hi\n!'

可以看到,${}计算部分被执行,而其他的部分被保留原样输出。

其另外一种语法:

String.raw(callSite, ...substitutions)

  • callSite
    一个模板字符串的“调用点对象”。类似{ raw: ['foo', 'bar', 'baz'] }
  • ...substitutions
    任意个可选的参数,表示任意个内插表达式对应的值。

看起来比较空洞,看一个例子:

String.raw({
  raw: ['foo', 'bar', 'baz']
}, 2 + 3, 'Java' + 'Script');
//等同于`foo${2 + 3}bar${'Java' + 'Script'}baz`

raw走一位,然后,substitutions的走一位。就这么简单。

如果,substitutions的长度不够长会怎嘛用呢,当然是直接跳过,进入下一循环。

String.raw({
  raw: ['foo', 'bar', 'baz']
}) // 'foobarbaz'

反过来, raw的长度不够呢?

String.raw({
  raw: ['foo']
}, 2 + 3, 'Java' + 'Script')  // 'foo'

结果是,停止往下走,一单raw走完,over!!!

这里比较特殊的是字符串:

String.raw({ raw: 'ABCD' }, 0, 1, 2) //  'A0B1C2D'

其实也很好理解,对吧,取下标吗!

我们再换类数组, 也是可以的,那么 arguments参数也是可以的。

String.raw({ raw: { 
    length: 2 ,
    0: "A",
    1: "B"
}}, 0) //  'A0B'

我们再试试把类数组的length去掉,发现不可以了,真有些意思。

String.raw({ raw: { 
    0: "A",
    1: "B"
}}, 0)  // ''

留一个问题,如果实现了迭代器的对象,能不能被正确解析呢?

小结

今天你收获了吗?