1. 程式人生 > >ES6學習筆記(一)——字串的擴充套件

ES6學習筆記(一)——字串的擴充套件

預備知識

  • utf-16:把Unicode字符集的抽象碼位對映為16位長的整數(即碼元)的序列,Unicode字元的碼位,需要1個或2個16位的碼元來表示。
  • utf-32:使用32個位元對每個Unicode碼位進行編碼,編碼長度是固定的,即32位。
  • js內部,字元以utf-16的格式儲存,每個字元固定為兩個位元組。
  • String.length的結果不是字串中字元的個數,而是編碼結果位元組數/2位元組,如果有一個字元的碼點超過0xffff,它對length的貢獻是2。

ES6對Unicode的支援

1. 字元的Unicode表示法

字元”?”的utf-16編碼結果為”D842 DFB7”,utf-32編碼結果為”20BB7”,es6對\u20BB7的解讀是兩個字元,對\u{20BB7}的解讀是一個字元,二三兩行程式碼表明 ,大括號表示法和四位元組的utf-16編碼是等價的。

console.log('\u20BB7')
console.log('\u{20BB7}')
console.log('\uD842\uDFB7')

result

2.codePointAt()

對於Unicode碼點大於0xffff的字元,js會認為它們是兩個字元。此時charAt()無法讀取整個字元,charCodeAt()分別返回前兩個位元組和後兩個位元組的值。
這裡寫圖片描述
codePointAt(index)能處理4個位元組儲存的字元,返回10進位制的碼點。引數index不是字元在字串中的位置,而是字元相對於字串的length的位置。可以用toString()方法轉換進位制。
這裡寫圖片描述
上面字串s的編碼結果為 D842 DFB7 0061,如果codePonitAt(index)恰好在一個4位元組長度字元的起始編碼位置,結果能返回4位元組的碼點,否則會返回低2位元組的編碼。
這裡寫圖片描述


for…of迴圈能正確識別32位的utf-16字元

for (let ch of s) {
  console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
// 61

3.String.fromCodePoint()

ES5的String.fromCharCode(code)方法,用於從碼點返回對應字元,但是code如果超過0xffff,結果只會對低2個位元組進行轉換。
ES6的String.fromCodePoint(code)可以識別大於0xffff的碼點。

String.fromCharCode(0x20BB7)// "ஷ"
// equal to
String.fromCharCode(0x0BB7)// 只對低2位元組進行轉換

4.at()

ES5的charAt(index)不能識別碼點大於0xffff的字元,ES6的at(index)則可以識別碼點大於0xffff的字元。

5.normalize()

許多歐洲語言有語調符號和重音符號。為了表示它們,Unicode 提供了兩種方法。一種是直接提供帶重音符號的字元,比如Ǒ(\u01D1)。另一種是提供合成符號(combining character),即原字元與重音符號的合成,兩個字符合成一個字元,比如O(\u004F)和ˇ(\u030C)合成Ǒ(\u004F\u030C)。

這兩種表示方法,在視覺和語義上都等價,但是 JavaScript 不能識別。

'\u01D1'==='\u004F\u030C' //false

'\u01D1'.length // 1
'\u004F\u030C'.length // 2

ES6 提供字串例項的normalize(parameter)方法(具體引數及其意義,用時補充),用來將字元的不同表示方法統一為同樣的形式,這稱為 Unicode 正規化。

'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

6.includes(), startsWith(), endsWith()

傳統上js只有indexOf()方法用來確定字串是否包含在另一個字串裡面。ES6新增下面三個方法。
syntax:
includes(string, index)
startsWith(string, index)
endsWith(string, index)
三種方法的返回值都是布林值。index指開始搜尋位置。

7.repeat()

構造並返回一個新字串,該字串包含被連線在一起的指定數量的字串的副本。指定副本數量如果不是整數,實行上取整。

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

'na'.repeat(-0.9) // ""
'na'.repeat(2.9) // "nana"

8.padStart(), padEnd()

syntax:
padStart(len, string)
padEnd(len, string)
len–補全後字串長度;
string(optional)–用於補全的字串。預設時候為空格。
這兩個方法都返回一個新新字串,原字串無改動。如果len小於等於原字串長度,則返回原字串。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

9.模板字串

用反引號(`)標識,可以當普通字串使用,也可以定義多行字串,或者在字串中嵌入變數。
syntax:

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

模板字串中的多行字串,所有空格、縮排和回車都會被保留。${ }中是表示式,可以是變、引用的物件屬性和js表示式(包括函式呼叫語句)。

11.標籤模板(tagged template)

函式名後緊跟著模板字串,該函式將被呼叫來處理這個模板字串。

let a = 5;
let b = 10;

tag`Hello ${ a + b } world ${ a * b }`;
// 等同於
tag(['Hello ', ' world ', ''], 15, 50);