😁 作者简介:一名大三的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:JavaScript进阶指南
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气
🔥前言:
这是自己在学习JavaScript的学习笔记和总结,希望可以帮助到你,这里简述的是字符串的扩展,需要一定的字符串基础。
字符串扩展
4.1 字符的Unicode表示法
4.1.1 什么是码元和码点
码元:在早期的时候,Js的编码规范是[16位的字符编码(USC-2)],规定了每一个字对应[16位]的空间,16位的空间被称为码元
码点:每一个Unicode字符都有一个ID,它是个整数,从0开始,这个数字被称为字符码点
字符串的所有属性和方法(像是 length 属性和 chatAt 方法)都是基于 16 位的码元,尤其是索引也是基于这个16位单元来表示的。但是后来生僻字越来越多,16位的空间不够用了
就把编码方式换成了utf-16,utf-16允许一个文字占用16位的空间也就是一个码元或者32位的空间就是两个码元,一些特殊的文字就占用了两个码元,像’𠮷’和’𧨁’就占用了两个码元
4.1.2 基本使用
JavaScript允许采用**\uxxxx形式表示一个字符,其中xxxx**表示字符的Unicode码点
"\u0061"
//a
但是这种表示法只限于码点在\u0000~\uFFFF之间的字符,超出这个范围的字符,必须用2个双字节的形式表达
"\uD842\uDFB7"
//𠮷
"\u20bb7"
// 7
上面的代码表示,如果直接在\u后面跟上超过0xFFFF的数值(比如\u20bb7),JavaScript会理解成\u20bb+7。由于\u20bb是一个不可以打印字符,所以只会显示一个空格,后面跟着一个7
ES6中对此做出改进,只要将码点放入大括号中,就能正确解读该字符
"\u{20bb7}"
//𠮷
4.2 codePointAt()
JavaScript内部,字符以utf-16的格式储存,每一个字符固定为2个字节,当出现想要4个字节储存的字符,那么javaScript会认为它们是2个字符。
var s='𠮷'
let a=s.length //2
let b=s.charAt(0) //''
let c=s.charAt(1) //''
let d=s.charCodeAt(0) //55362
let e=s.charCodeAt(1) //57271
上面的代码中,汉字“𠮷”(注意,这个字可不是吉祥的”吉“)的码点是0x20bb7,UTF-16编码为0xD842,0xDFB7(十进制为55362,57271)想要四个字节储存,但是4个字节的字符,JavaScript不能正确处理,字符长度会被误判为2,charAt并不能正确返回整个字符,charCodeAt方法只能分别返回前2个字节和后2个字节
ES6提供了codePointAt方法,是可以正确处理4个字节储存的字符的,返回一个字符的码点
var s='𠮷a'
let a1=s.codePointAt(0) //134071
let a2=s.codePointAt(1) //57271
let a3=s.codePointAt(2) //97
在JavaScript中会将这个”𠮷a"视为3个字符,所以第一个字符正确识别了“𠮷”,但是在第二个字符中,就是返回后2个字节啦,第三个字符也是如此,这时候的codePointAt和charCodeAt返回的结果是相同的
⭐️ 大家可以注意到,按照索引去理解的话,应该是0就是 “𠮷”,而1就是 "a"才正确嘛,解决这个问题的办法可以使用 for…of…,因为for…of…会按照字符去读取,一个字符一个字符遍历,所以其可以正确识别32位的UTF-16的字符
var s='𠮷a'
for(let c of s){
console.log(ch.codePointAt(0).toString(16))
}
//20bb7
//61
codePointAt是测试一个字符是由2个字节组成还是4个字节组成的最简单的方法
function is32Bit(c){
return c.codePointAt(0)>0xFFFF
}
var a= is32Bit("𠮷") //true
var b=is32Bit("a") //false
4.3 String.fromCodePoint
这个方法用于从码点返回对应字符,其中fromCharCode与fromCodePoint的区别和上文的codePointAt和charCodeAt是一样的
String.fromCodePoint(0x20BB7)
//𠮷
❗️ 注意:fromCodePoint是定义在String对象上的,而codePointAt方法是定义在字符串的实例对象上的
4.4 字符串的遍历器接口
for…of循环,这个遍历器可以遍历字符串,并且其最大的优点就是 可以识别大于0xFFFF的码点
4.5 at()
这个方法和charAt方法差不多,返回给定的字符串位置,但是唯一不同的是:at()这个方法是可以识别Unicode编号大于0xFFFF的字符的,不过这个方法必须要通过垫片库来实现
4.6 includes(),startWith(),endsWith()
传统上 javaScript值有indexOf方法用来确定一个字符串是否包含在另一个字符中,ES6又提供了3种新方法:
- includes():返回布尔值,表示是否找到了参数字符
- startsWith():返回布尔值,表示参数字符串是否在源字符串的头部
- endsWith():返回布尔值,表示参数字符串是否在源字符串尾部
var s='Hello World!'
console.log(s.includes('Hello'))
console.log(s.endsWith('!'))
console.log(s.startsWith('e'))
//true
//true
//false
这三个方法都支持第二个参数,表示开始搜索的位置(这样可以节省搜索时间)
4.7 repeat()
repeat方法会返回一个新的字符串,表示将原字符串重复n次
let x1='x'.repeat(3)
let na1='na'.repeat(2)
console.log(x1)
console.log(na1)
⭐️ 注意点:
- 参数如果是小数会被取整
- 参数如果是负数或者Infinity会报错
- 参数如果是0 ~ -1之间的小数,则等同于0
- 参数NaN等同于0
4.8 padStart(),padEnd()
这个两个方法是字符串补全长度的功能,如果某一个字符串不够指定长度,会在头部或者尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。
'x'.padStart(5,'ab') //ababx
'x'.padEnd(5,'ab') //xabab
第一个参数用来指定字符的最小长度,第二参数则用来补全的字符串
⭐️ 注意点:
-
如果原字符串的长度等于或者大于指定长度,则返回原来字符串
'xxx'.padStart(2,'ab') //xxx
-
如果用来补全的字符串与原字符串的长度之和超过指定了指定的最小长度,则会截去超出位数补全字符串
'abc'.padStart(10,'0123456789')//0123456abc
-
如果省略第二个参数,则会用空格补全
用法
-
为数值补全指定位数
'1'.padStart(10,'0')//0000000001
-
提示字符串的格式,有点类似字符串的拼接
'12'.padStart(10,'YYYY-MM-DD') //"YYYY-MM-12"