亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

ES6+ 字符串的擴展

1. 前言

由于歷史原因,在 JavaScript 創建之初,市面上的編碼方式還是很混亂的,JavaScript 在創建之初,使用的是 1990 年公布的 UCS-2 的編碼方法,使用 2 個字節表示 1 個字符,那時 UTF-8、UTF-16、UTF-32 還沒有完全確定?,F在的 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(0));	// 24917 轉成十六進制 0x6155
console.log(str.charCodeAt(1));	// 35838 轉成十六進制 0x8bfe
console.log(str.charCodeAt(2));	// NaN

看上面代碼打印結果,并轉成十六進制了,而 Unicode 表示是把前面的 0x 換成 u,這就是 Unicode 的表示。在 ES5 中還存在一個問題,實例如下:

let str = '?';

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

console.log(str.charCodeAt(0)) // 55358 轉成十六進制 0xd83e
console.log(str.charCodeAt(1)) // 56618 轉成十六進制 0xdd2a

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

上面的代碼可以看到 str 是一個 Emoji 的表情符號,使用length 屬性可以得到它的長度是 2,這完全不符合我們對這個字符串的定義。這就是 JavaScript 的編碼問題。為解決 charCodeAt() 方法獲取字符碼位錯誤的問題,新增 codePointAt() 方法。

codePointAt() 方法完全支持 UTF-16,參數接收的是編碼單元的位置而非字符位置,返回與字符串中給定位置對應的碼位,即一個整數,如下實例:

let str = '?';

console.log(str.codePointAt(0)) // 129322 轉成十六進制 0x1f92a => u1f92a
console.log(str.codePointAt(1)) // 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 的增強,還有對字符串增加了遍歷接口,非常實用。