ES6中字符串的使用方法扩展


Posted in Javascript onJune 04, 2019

字符的Unicode表示法

JavaScript允许采用\uxxxx形式表示一个字符,其中“xxxx”表示字符的码点。

"\u0061"
// "a"

但是,这种表示法只限于\u0000——\uFFFF之间的字符。超出这个范围的字符,必须用两个双字节的形式表达。

"\uD842\uDFB7"
// "?"
"\u20BB7"
// " 7"

上面代码表示,如果直接在\u后面跟上超过0xFFFF的数值(比如\u20BB7),JavaScript会理解成\u20BB+7。由于\u20BB是一个不可打印字符,所以只会显示一个空格,后面跟着一个7。

ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符。

下面代码中,最后一个例子表明,大括号表示法与四字节的UTF-16编码是等价的。

"\u{20BB7}"
// "?"
"\u{41}\u{42}\u{43}"
// "ABC"
let hello = 123;
hell\u{6F} // 123
'\u{1F680}' === '\uD83D\uDE80'
// true

有了上述表示法之后,JavaScript共有6种方法可以表示一个字符。

'\z' === 'z' // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true

codePointAt()

ES6提供了codePointAt方法,能够正确处理4个字节储存的字符,返回一个字符的码点。

var 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方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。

var 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字符。

var s = '?a';
for (let ch of s) {
 console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
// 61

String.fromCodePoint()

ES5提供String.fromCharCode方法,用于从码点返回对应字符,但是这个方法不能识别32位的UTF-16字符(Unicode编号大于0xFFFF)。

下面代码中,String.fromCharCode不能识别大于0xFFFF的码点,所以0x20BB7就发生了溢出,最高位2被舍弃了,最后返回码点U+0BB7对应的字符,而不是码点U+20BB7对应的字符。

String.fromCharCode(0x20BB7)
// "ஷ"

ES6提供了String.fromCodePoint方法,可以识别0xFFFF的字符,弥补了String.fromCharCode方法的不足。在作用上,正好与codePointAt方法相反。

String.fromCodePoint(0x20BB7)
// "?"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true

上面代码中,如果String.fromCodePoint方法有多个参数,则它们会被合并成一个字符串返回。

注意,fromCodePoint方法定义在String对象上,而codePointAt方法定义在字符串的实例对象上。

字符串的遍历器接口

ES6为字符串添加了遍历器接口(详见《Iterator》一章),使得字符串可以被for...of循环遍历。

for (let codePoint of 'foo') {
 console.log(codePoint)
}
// "f"
// "o"
// "o"

at()

目前,ES6有一个提案,提出字符串实例的at方法,可以识别Unicode编号大于0xFFFF的字符,返回正确的字符。

'abc'.at(0) // "a"
'?'.at(0) // "?"

normalize()

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

'\u01D1'==='\u004F\u030C' //false
'\u01D1'.length // 1
'\u004F\u030C'.length // 2

上面代码表示,JavaScript将合成字符视为两个字符,导致两种表示方法不相等。

ES6提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为Unicode正规化。

'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

normalize方法可以接受一个参数来指定normalize的方式,参数的四个可选值如下。

  • NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
  • NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
  • NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“?帧焙汀跋蚕病薄#ㄕ庵皇怯美淳倮??ormalize方法不能识别中文。)
  • NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。

下面代码表示,NFC参数返回字符的合成形式,NFD参数返回字符的分解形式。
不过,normalize方法目前不能识别三个或三个以上字符的合成。这种情况下,还是只能使用正则表达式,通过Unicode编号区间判断。

'\u004F\u030C'.normalize('NFC').length // 1
'\u004F\u030C'.normalize('NFD').length // 2

includes(), startsWith(), endsWith()

传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

  1. includes():返回布尔值,表示是否找到了参数字符串。
  2. startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
  3. endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。
var s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

这三个方法都支持第二个参数,表示开始搜索的位置。

下面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

var s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。

参数如果是小数,会被取整。

如果repeat的参数是负数或者Infinity,会报错。

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
'na'.repeat(2.9) // "nana"
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError

padStart(),padEnd()

ES7推出了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart用于头部补全,padEnd用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

上面代码中,padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

$('#result').append(`
 There are <b>${basket.count}</b> items
 in your basket, <em>${basket.onSale}</em>
 are on sale!
`);

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Code: write(s,d) 输出连续字符串
Aug 19 Javascript
javascript 简单抽屉效果的实现代码
Mar 09 Javascript
javascript 得到变量类型的函数
May 19 Javascript
JavaScript入门之事件、cookie、定时等
Oct 21 Javascript
Javascript全局变量var与不var的区别深入解析
Dec 09 Javascript
Angularjs全局变量被作用域监听的正确姿势
Feb 06 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
Jul 06 Javascript
React-native桥接Android原生开发详解
Jan 17 Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
Mar 28 Javascript
JavaScript如何实现元素全排列实例代码
May 14 Javascript
js获取本日、本周、本月的时间代码
Feb 01 Javascript
如何实现vue的tree组件
Dec 03 Vue.js
详解vue-cli3多页应用改造
Jun 04 #Javascript
javascript异步处理与Jquery deferred对象用法总结
Jun 04 #jQuery
浅谈react-router@4.0 使用方法和源码分析
Jun 04 #Javascript
vue axios post发送复杂对象问题
Jun 04 #Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
Jun 04 #Javascript
vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)
Jun 04 #Javascript
JavaScript实现页面中录音功能的方法
Jun 04 #Javascript
You might like
基于PHP array数组的教程详解
2013/06/05 PHP
PHP删除指定目录中的所有目录及文件的方法
2015/02/26 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
PHP实现生成带背景的图形验证码功能
2016/10/03 PHP
七种PHP开发环境搭建工具
2020/06/28 PHP
Open and Print a Word Document
2007/06/15 Javascript
jQuery Ajax 实例全解析
2011/04/20 Javascript
JQuery与JSon实现的无刷新分页代码
2011/09/13 Javascript
node.js chat程序如何实现Ajax long-polling长链接刷新模式
2012/03/13 Javascript
javascript中数组的sort()方法的使用介绍
2013/12/18 Javascript
编写高效jQuery代码的4个原则和5个技巧
2014/04/24 Javascript
Nodejs学习笔记之测试驱动
2015/04/16 NodeJs
JavaScript使用encodeURI()和decodeURI()获取字符串值的方法
2015/08/04 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
微信小程序入门教程
2016/11/18 Javascript
jQuery基于xml格式数据实现模糊查询及分页功能的方法
2016/12/25 Javascript
js 取消页面可以选中文字的功能方法
2018/01/02 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
详解微信小程序开发聊天室—实时聊天,支持图片预览
2019/05/20 Javascript
jQuery实现点击滚动到指定元素上的方法分析
2020/03/19 jQuery
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python实现过滤单个Android程序日志脚本分享
2015/01/16 Python
selenium+python设置爬虫代理IP的方法
2018/11/29 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
200行python代码实现2048游戏
2019/07/17 Python
详解python中的模块及包导入
2019/08/30 Python
Python3多线程版TCP端口扫描器
2019/08/31 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
Python中__repr__和__str__区别详解
2019/11/07 Python
python应用Axes3D绘图(批量梯度下降算法)
2020/03/25 Python
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
您附近的水疗和健康场所:Spafinder(美国)
2019/07/05 全球购物
类、抽象类、接口的差异
2016/06/13 面试题
合作意向书范本
2014/03/31 职场文书
海康机器人重磅发布全新算法开发平台VM4.2
2022/04/21 数码科技