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 相关文章推荐
JS日历 推荐
Dec 03 Javascript
jQuery Select(单选) 模拟插件 V1.3.62 改进版
Jul 17 Javascript
从零开始学习jQuery (八) 插播:jQuery实施方案
Feb 23 Javascript
探索Emberjs制作一个简单的Todo应用
Nov 07 Javascript
js中符号转意问题示例探讨
Aug 19 Javascript
js AppendChild与insertBefore用法详细对比
Dec 16 Javascript
jquery实现图片按比例缩放示例
Jul 01 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
Jan 04 Javascript
JavaScript 上传文件(psd,压缩包等),图片,视频的实现方法
Jun 19 Javascript
详解微信小程序中的页面代码中的模板的封装
Oct 12 Javascript
在Vue项目中引入腾讯验证码服务的教程
Apr 03 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
Aug 01 Javascript
详解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 base64+gzinflate压缩编码和解码代码
2008/10/03 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
基于PHP读取TXT文件向数据库导入海量数据的方法
2013/04/23 PHP
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
JS实现队列与堆栈的方法
2016/04/21 Javascript
微信小程序 定义全局数据、函数复用、模版等详细介绍
2016/10/27 Javascript
详解angular中的作用域及继承
2017/05/31 Javascript
jQuery实现鼠标响应式透明度渐变动画效果示例
2018/02/13 jQuery
微信小程序如何像vue一样在动态绑定类名
2018/04/17 Javascript
使用Phantomjs和Node完成网页的截屏快照的方法
2019/07/16 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
Vue内部渲染视图的方法
2019/09/02 Javascript
js实现验证码功能
2020/07/24 Javascript
[01:45]亚洲邀请赛互动指南虚拟物品介绍
2015/01/30 DOTA
python实现解数独程序代码
2017/04/12 Python
Python实现的视频播放器功能完整示例
2018/02/01 Python
Python学习笔记之视频人脸检测识别实例教程
2019/03/06 Python
简单介绍django提供的加密算法
2019/12/18 Python
vue常用指令代码实例总结
2020/03/16 Python
Python实现发票自动校核微信机器人的方法
2020/05/22 Python
python如何调用百度识图api
2020/09/29 Python
Pycharm操作Git及GitHub的步骤详解
2020/10/27 Python
微软美国官方网站:Microsoft美国
2018/05/10 全球购物
 Alo Yoga官网:购买瑜伽服装
2018/06/17 全球购物
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
专营店会计助理岗位职责
2013/11/29 职场文书
关于国庆节的演讲稿
2014/09/05 职场文书
九一八事变演讲稿范文
2014/09/14 职场文书
迁徙的鸟观后感
2015/06/09 职场文书
2019年教师入党申请书
2019/06/27 职场文书
springboot如何接收application/x-www-form-urlencoded类型的请求
2021/11/02 Java/Android
梳理总结Python开发中需要摒弃的18个坏习惯
2022/01/22 Python