好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ES6+ 字符串的扩展

ES6+ 字符串的扩展

1. 前言

由于历史原因,在 JavaScript 创建之初,市面上的编码方式还是很混乱的,JavaScript 在创建之初,使用的是 1990 年公布的 UCS-2 的编码 方法 ,使用 2 个字节表示 1 个字符,那时 UTF-8、UTF-16、UTF-32 还没有完全确定。现在的 JavaScript 主要使用的是 UTF-16 来存储的。

但针对于纷繁复杂的网页字符是不能完全地覆盖的,在早期使用浏览器时,经常会在浏览器中选择字符串编码方式。那么有没有一种编码可以涵盖世界上的所有字符呢?答案是有的 ——Unicode。它是 一个 字符集,它的定义很简单,用 一个 码点 (code point) 映射 一个 字符。码点值的范围是从 U+0000 到 U+10FFFF,可以表示超过 110 万个符号。

所以后来的 ECMAScript 一直致力于 解决 历史遗留的问题和统一浏览器的编码方式。这时 ES6 出来了,对 Unicode 进行了加强,也修复了 ES5 中的问题。在 模版字符串 的小节中已经学习了关于字符串模板字符串的 内容 ,本节我们继续学习 ES6 中字符串其他的扩展。

2. Unicode

Unicode 只是 一个 符号集,它只规定了符号的二进制 代码 ,却没有规定这个二进制 代码 应该如何存储。所以出现了 Unicode 的多种存储方式,不同的实现导致了 Unicode 在很长一段时间内无法推广,而且本来 英文字母 只用 一个 字节存储就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个 英文字母 前都必然有二到三个字节是空,这对于存储来说是极大的浪费,文本 文件 的大小会因此大出二三倍,这是无法接受的。

首先我们来看下 一个 字符是怎么表示的,JavaScript 提供了 charCodeAt() 获取 指定位置的字符的值,返回的值在 0 到 65535 之 间的 整数。

  var  str  =   ''  ; 
console .  log  ( str .  charCodeAt  (  )  )  ; 	 // 24917 转成十六进制 0x6155 
console .  log  ( str .  charCodeAt  (  )  )  ; 	 // 35838 转成十六进制 0x8bfe 
console .  log  ( str .  charCodeAt  (  )  )  ; 	 // NaN 
 

看上面 代码 打印结果,并转成十六进制了,而 Unicode 表示是把前面的 0x 换成 u,这就是 Unicode 的表示。在 ES5 中还存在 一个 问题,实例如下:

  let  str  =   '?'  ; 

console .  log  ( str . length )    // 2 ,str 是 Emoji 表情符 

console .  log  ( str .  charCodeAt  (  )  )   // 55358 转成十六进制 0xd83e 
console .  log  ( str .  charCodeAt  (  )  )   // 56618 转成十六进制 0xdd2a 

console .  log  (  '\ud83e\udd2a'   ===   '?'  )   // true 
 

上面的 代码 可以看到 str 是 一个 Emoji 的表情符号,使用length 属性 可以得到它的长度是 2,这完全不符合我们对这个字符串的定义。这就是 JavaScript 的编码问题。为 解决 charCodeAt() 方法 获取 字符码位 错误 的问题,新增 codePointAt() 方法 。

codePointAt() 方法 完全 支持 UTF-16,参数接收的是编码单元的位置而非字符位置,返回与字符串中给定位置对应的码位,即 一个 整数,如下实例:

  let  str  =   '?'  ; 

console .  log  ( str .  codePointAt  (  )  )   // 129322 转成十六进制 0x1f92a => u1f92a 
console .  log  ( str .  codePointAt  (  )  )   // 56618 转成十六进制 0xdd2a => udd2a 
 

上面的 代码 中,第二行打印位置 0 处的编码单元开始的码位,此例是从这个编码单位开始的两个编码单 元组 合的字符(四个字节),所以会打印出所有码位,即四字节的码位 129322 即 0x1f92a,大于 0xffff,也证明了是占四个字节的存储空间。

3. 字符串的遍历器接口

ES6 为字符串 添加 了可遍历接口,使得字符串可以被 for...of 进行循环遍历。如下实例:

  var  str  =   '网?'  ; 
 for   (  let  item  of  str )   { 
  console .  log  ( item )  ; 
 } 
 // 慕 
 // 课 
 // 网 
 // ? 
 

上面的 代码 中,最后 一个 是 emoji 表情字符,存储时占 4 个字节,但是通过 for...of 可以正确地迭代为 一个 字符。在 ES5 中则不行,我们来看个实例,把上面的字符串使用 ES5 中的 split 方法 把字符串转化成数组:

  var  str  =   '网?'  ; 
console .  log  ( str .  split  (  ''  )  ) 
 // ["慕", "课", "网", "?", "?"] 
 

从上面的 代码 中可以清晰地反映出表情字符是占四个字节,但是,ES5 不能把它当作 一个 字节来处理所以就会出现数组后两个元素的样子。这也是 ES5 存在的主要问题之一,可以通过迭代器对复杂的字符串进行正确的处理。

4. 小结

ES6 还提供了其他的字符串操作的 方法 ,接下来的几节专门讲解字符串中新增的 方法 ,更好地 解决 实际的开发问题。另外,ES6 还 增加 了模版字符串和带 标签 的模板字符串,在 模板字符串 中进行了讲解,遗忘的可以去看看。本节主要讲解了,字符串对 Unicode 的增强,还有对字符串 增加 了遍历接口,非常实用。

查看更多关于ES6+ 字符串的扩展的详细内容...

  阅读:58次

上一篇

下一篇

第1节:ES6+ 简介    第2节:ES6 环境配置    第3节:ES6+ let    第4节:ES6+ const    第5节:ES6+ 展开语法    第6节:ES6+ 剩余参数    第7节:ES6+ 解构赋值    第8节:ES6+ 模版字符串    第9节:ES6+ 箭头函数    第10节:ES6+ 数值扩展    第11节:ES6+ isFinite()&isNaN()    第12节:ES6+ Number 对象的方法    第13节:ES6+ Math 对象的扩展    第14节:ES6+ includes()    第15节:ES6+ 字符串的扩展    第16节:ES6+ startsWith()    第17节:ES6+ endsWith()    第18节:ES6+ repeat()    第19节:ES6+ padStart()    第20节:ES6+ padEnd()    第21节:ES6+ trim()    第22节:ES6+ Array.from()    第23节:ES6+ of()    第24节:ES6+ find()和findIndex()    第25节:ES6+ copyWithin()    第26节:ES6+ fill()    第27节:ES6+ isArray()    第28节:ES6+ 对象的扩展    第29节:ES6+ flat()    第30节:ES6+ 可选链操作符    第31节:ES6+ Object.is()    第32节:ES6+ Object.assign()    第33节:ES6+ Object.keys()    第34节:ES6+ Object.values()    第35节:ES6+ Object.entries()    第36节:ES6+ 数据结构扩展    第37节:ES6+ Set    第38节:ES6+ WeakSet    第39节:ES6+ Map    第40节:ES6+ WeakMap    第41节:ES6+ Symbol    第42节:ES6+ for...of    第43节:ES6+ 迭代协议    第44节:ES6+ 实现一个简版的 Promise    第45节:ES6+ Promise 基础    第46节:ES6+ Promise 进阶    第47节:ES6+ Generator 基础    第48节:ES6+ Generator 函数应用    第49节:ES6+ async/await    第50节:ES6+ Class 前置知识    第51节:ES6+ Class    第52节:ES6+ Proxy    第53节:ES6+ Reflect(一)    第54节:ES6+ Reflect(二)    第55节:ES6+ 模块化(一)    第56节:ES6+ 模块化(二)    第57节:ES6实战1-实现Vue3 reactive 源码    第58节:ES6实战2-实现 Vue3 effect 源码    第59节:ES6 实战2-封装请求    第60节:ES6+ 实战3-代码整洁之道    第61节:ES6 Map原理分析    第62节:ES6module语法加载importexport    第63节:ES6的循环与可迭代对象示例详解