ES6學習筆記4--字串的擴充套件

Pig_Gril發表於2020-12-26
  • 字元的Unicode表示法

ES5允許採用  \uxxxx 形式表示一個字元。xxxx表示字元的Unicode碼點.

\uxxxx 表示法只限於碼點在 \u0000 ~ \uFFFF 之間的字元。超出這個範圍的字元,必須用兩個雙位元組的形式表示。

ES6 可以使用\u{xxxxx},將碼點放入大括號中,可以正確解讀該字元

//? 的 unicode U+1F9E1
/*(1)ES6*/
let a = "\u{1F9E1}"
a //"?"

/*(2)ES5僅支援 \uxxxx表示法,超過範圍的必須用兩個UTF-16碼元來表示*/
let first = "\u{1F9E1}"[0].codePointAt(0).toString(16);  //d83e
let second = "\u{1F9E1}"[1].codePointAt(0).toString(16);  //dde1

let b = '\ud83e\udde1'  
b //"?"

//將UTF-32字元轉換為兩個UTF-16的表示法

function toUTF16(codePoint) {
    var TEN_BITS = parseInt('1111111111', 2);
    function u(codeUnit) {
        return '\\u'+codeUnit.toString(16).toUpperCase();
    }

    if (codePoint <= 0xFFFF) {
        return u(codePoint);
    }
    codePoint -= 0x10000;

    // Shift right to get to most significant 10 bits
    var leadingSurrogate = 0xD800 | (codePoint >> 10);

    // Mask to get least significant 10 bits
    var trailingSurrogate = 0xDC00 | (codePoint & TEN_BITS);

    return u(leadingSurrogate) + u(trailingSurrogate);
}

toUTF16(0x1F9E1);  //"\uD83E\uDDE1"


  • 擴充套件(在html 頁面使用Unicode ) UnicodeTable
/*(3)HTML 語法*/
&#x1f9e1;
  • 字串的遍歷器介面

ES6 為字串新增了遍歷器介面。使得字串可以被 for...of  迴圈遍歷。

且可以識別大於 0xFFFF 的碼點。傳統的 for 迴圈無法識別這樣的碼點。

for(let codePoint of 'foo'){

    console.log(codePoint);
}

//'f' 
//'o'
//'o'

//對於碼點超過 0xFFFF 的Unicode字元。
let text = String.fromCodePoint(0x20bb7);

text //"?"

//傳統的for迴圈
for(let i=0;i<text.length;i++){
  console.log(text[i]);
}
//"�"    
//"�"

//ES6 增加 for...of 迴圈
for(let i of text){
   console.log(i);
}
//"?"
  • 直接輸入U+2028 和 U+2029

JavaScript 字串允許直接輸入字元以及輸入字元的轉義形式。

'中' === '\u4e2d' //true;

// \u4e2d 為 中 的轉義形式

JavaScript 規定有5個字元,不能直接在字串中使用。只可以使用轉義形式

U+005C 反斜槓(\)
U+000D 回車
##U+2028 行分隔符
##U+2029 段分隔符
U+000A 換行符 

//但由於 在Json格式中可以直接使用U+2028 行分隔符 U+2029 段分隔符。
所以ES2019  允許在JavaScript字串中直接輸入U+2028 行分隔符 U+2029 段分隔符。
  • JSON.stringify() 

JSON資料必須是UTF-8 編碼。

UTF-8 標準規定 0xD8000xDFFF 之間的碼點不可單獨使用,必須配對使用。這是對碼點大於 0xFFFF 字元的一種變通方法。

但是JSON.stringify() 可能會返回 0xD800 0xDFFF 之間的單個碼點。

所以如果遇到 0xD8000xDFFF 之間的單個碼點或者不存在的配對形式.他會返回轉義字元

/*單個在 0xD800 到 0xDFFF之間的碼點,返回轉義的字串*/
JSON.stringify('\u{D834}')  // "'\ud834'"  

/*兩個在 0xD800 到 0xDFFF之間的碼點,但不存在配對形式,返回轉義的字元*/ 
JSON.stringify('\uDF06\uD834') //"'\udf06\ud834'"

/*兩個在 0xD800 到 0xDFFF之間的碼點,存在配對形式,返回正確的字元*/ 
JSON.stringify('\uD834\uDF06') // "'?'"
  • 模板字串

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

//普通字串
let a = `In JavaScript '\n' is a line-feed.`

/*輸出結果
"In JavaScript '
' is a line-feed."
*/

//多行字串
let a = `In JavaScript this is
not legal
`
/*輸出結果
"In JavaScript this is
not legal
"
*/

//在字串中嵌入變數
let name = "Bob", time = "today";
let a = `Hello ${name}, how are you ${time}?`

/*輸出結果
"Hello Bob, how are you today?"
*/

/*注意點:
(1)若要在模板字串中使用反引號,前面要用反斜槓進行轉義
(2)如果使用模板字串表示多行字串,所有空格和鎖緊都會被保留在輸出之中
(3)模板字串中嵌入變數,需要將變數名寫在 ${}之中。
*/
  • 標籤模板

標籤模板:將模板字串緊跟在函式名後面,改函式將被呼叫處理這個模板字串。是函式呼叫的一種特殊形式。

如果模板標籤字元裡有變數,就會將模板字串先處理成多個引數在呼叫函式。

let a = 5 ;
let b = 10;
 
tag`Hello ${a+b} world ${a*b}`;

//等同於

tag(['Hello','world',''],15,20);
/*
該陣列成員時模板字串中沒有被變數替換的部分。
變數替換髮生在陣列的第一個成員和第二個成員之間、第二個與第三個成員之間、以此類推。
*/

“標籤模板”的一個重要應用,就是過濾 HTML 字串,防止使用者輸入惡意內容。

let message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;
function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i = 1; i < arguments.length; i++) {
    let arg = String(arguments[i]);
    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

 

相關文章