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 相关文章推荐
选择复选框按钮置灰否则按钮可用
May 22 Javascript
基于jQuery实现点击弹出层实例代码
Jan 01 Javascript
javascript显示上周、上个月日期的处理方法
Feb 03 Javascript
JavaScript+canvas实现七色板效果实例
Feb 18 Javascript
简单实现js点击展开二级菜单功能
May 16 Javascript
springmvc接收jquery提交的数组数据代码分享
Oct 28 jQuery
在小程序开发中使用npm的方法
Oct 17 Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 Javascript
如何用原生js写一个弹窗消息提醒插件
May 24 Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 Javascript
Node.js fs模块(文件模块)创建、删除目录(文件)读取写入文件流的方法
Sep 03 Javascript
手写Vue源码之数据劫持示例详解
Jan 04 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
全国FM电台频率大全 - 19 广东省
2020/03/11 无线电
如何写php程序?
2006/12/08 PHP
PHP学习散记_编码(json_encode 中文不显示)
2011/11/10 PHP
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
2012/03/07 PHP
php颜色转换函数hex-rgb(将十六进制格式转成十进制格式)
2013/09/23 PHP
WordPress迁移时一些常见问题的解决方法整理
2015/11/24 PHP
PHP 序列化和反序列化函数实例详解
2020/07/18 PHP
使用PHP开发留言板功能
2019/11/19 PHP
ExtJs3.0中Store添加 baseParams 的Bug
2010/03/10 Javascript
Javascript操作URL函数修改版
2013/11/07 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
2015/12/18 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
关于Bootstrap按钮组件消除黄框的方法
2017/05/19 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
2017/11/22 Javascript
Angular实现较为复杂的表格过滤,删除功能示例
2017/12/23 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
2018/09/17 Javascript
jquery 验证用户名是否重复代码实例
2019/05/14 jQuery
vuex存值与取值的实例
2019/11/06 Javascript
JavaScript监听一个DOM元素大小变化
2020/04/26 Javascript
在JavaScript中查找字符串中最长单词的三种方法(推荐)
2021/01/18 Javascript
[45:44]完美世界DOTA2联赛PWL S2 FTD vs PXG 第一场 11.27
2020/12/01 DOTA
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
Python标准库shutil用法实例详解
2018/08/13 Python
python地震数据可视化详解
2019/06/18 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
Python进阶之迭代器与迭代器切片教程
2020/01/29 Python
世界最大域名注册商:GoDaddy
2016/07/24 全球购物
如何用Python输出一个Fibonacci数列
2016/08/28 面试题
电子商务专业个人的自我评价
2013/11/19 职场文书
运动会广播稿300字
2014/01/10 职场文书
高二美术教学反思
2014/01/14 职场文书
关于是否需要写商业计划书
2014/02/07 职场文书
教师旷工检讨书
2015/08/15 职场文书
商务英语邮件开头问候语
2015/11/10 职场文书
Java各种比较对象的方式的对比总结
2021/06/20 Java/Android
MySql重置root密码 --skip-grant-tables
2022/04/11 MySQL