Skip to content

Latest commit

 

History

History

chapter-04

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

ES6 讀書會 - ECMAScript 6 入門

Chapter 4 - String

Prepared By Peng Jie

Table Of Content

使用 unicode 表示字串

TL;DR

  • Unicode 解決了不同文字編碼的問題。
  • 每個文字和符號都對應到一組 Code Point。
  • 十六進制格式:\u0000 - \uFFFF

延伸閱讀: Wiki - UnicodeUnicode字元平面對映

在 JavaScript 中的 String

  • UCS-2 encode。
  • Support UTF-16 encode。
  • Every string is 2 Byte

在 JavaScript 中,我們可以透過這樣的方式來表示字串:

const a = '\x61'; //a
const b = '\u0061'; // a

'\x61' === '\u0061'; // true

十六進制格式的兩個位元組成,代表一個編碼位置。
超出 \u0000 - \uFFFF 範圍必須要用兩個 Code Ponit 來表示。

在 ES6 中,改善了這個問題,將超出範圍的 Code Point 放入 { } 就可以了。

// ES5

const a = '\uD842\uDFB7'; // '𠮷' (4 Bytes)
const b = '\u20BB7'; // ₻7 (\u20BB+7)

// ES6

const c = '\u{20BB7}'; // '𠮷'

codePointAt 方法

簡單來說,透過 codePointAt() 可以正確處理 4 Byte 的字元。

const emoji = '\uD83D\uDE02'; // 😂

const tmp = emoji.codePointAt(0); // 128514 (十進制)
tmp.toString(16); //1f602 (十六進制)

emoji.codePointAt(1); // 56834 (十進制)

codePointAt() 方法回傳一個非負整數,它是 Unicode Code Point 的值。

String.fromCodePoint 方法

ES5 和 ES6 方法比較:

ES5:String.fromCharCode() < (0xFFFF)

ES6:String.fromCodePoint() > (0xFFFF)

String.fromCharCode() 會省略超過 0xFFFF 最高位元:

String.fromCharCode(0x1f602); //  => Actual:0xf602
String.fromCodePoint(0x1f602); // 😂 => success

String 的 iterator

ES6 的 for..of 在可以 Iterable 的物件上建立一個 loop。

(Iterator 的詳細介紹請期待下次的讀書會) 😉

const text = 'ES6 線上讀書會';

for (t of text) {
  console.log(t);
}

//

const emoji = String.fromCodePoint(0x1f602);

for (e of emoji) {
  console.log(e); // 😂
}

at 方法

at 方法目前還在 Proposal stage 0 階段

在前面 codePointAt() 提到了這個方法可以正確的處理 4 Byte 的字元,因為實際上它是被拆成兩組。 在這裡我們比較一下 charAtat 方法差異:

const text = 'abc';
const emoji = '😂';

console.log(text.charAt(0)); // a
console.log(emoji.charAt(0)); // �
console.log(emoji.at(0)); // 😂

at() 可以正確的回傳大於 0XFFFF 的字元。

normalize 方法

帶有語調和重音符號的字元,Unicode 有兩種方式可以表示:

例如 Ǒ 符號可以表達成:

  1. Ǒ(\u01D1) // 直接表達
  2. O(\u004F) + ˇ(\u030C) // 組合字元

所以直接表達組合字元是等價的嗎?

console.log('\u01D1' === '\u004f\u030C'); // false

normalize() 會根據你所指定的 Unicode 正規形式,將字符串正規化。

  • NFC:預設參數,標準形式規範組成。
  • NFD:標準形式規範分解。
  • NFKC:標準形式兼容組成。
  • NFKD:標準形式兼容分解。

更多參考 MDN:String.prototype.normalize()

加入 normalize() 後的比較結果:

console.log(
'\u01D1'.normalize() === '\u004f\u030C'.normalize()
); // true

字串確認

我們會使用 indexOf 來尋找字串首次出現的位置,lastIndex 來尋找字串最後出現的位置。

const text = 'ES6 Study';

console.log(text.indexOf('E')); // 0
console.log(text.indexOf('I')); // 不存在回傳 -1

//

const text2 = 'Happy Birthday';

console.log(text2.lastIndexOf('y')); // 13

includes 方法

確認字串是否包含如你參數中所指定的,回傳 boolean 值:

// Syntax:str.includes(searchString[, position])

const text = 'ES6 Study';

console.log(text.includes('ES6')); // true

startsWith 方法

確認字串的起始是否如你參數中所指定的,回傳 boolean 值:

// Syntax:str.startsWith(searchString[, position])

const text = 'ES6 Study';

console.log(text.startsWith('ES6')); // true

endsWith 方法

確認字串的尾部是否如你參數中所指定的,回傳 boolean 值:

// Syntax:str.endsWith(searchString[, position])

const text = 'ES6 Study';

console.log(text.endsWith('Study')); // true

repeat 方法

repeat() 方法回傳一個新字串。

const A = 'A';

console.log(A.repeat(2)); // AA
console.log(A.repeat(3.6)); // AAA
console.log(A.repeat(-1.2)); // RangeError

字串補全

目前 padStart()padEnd() 還在 Proposal stage-3 階段。

這兩個方法可以自動幫我們補全字串的長度,可以在 start 或是 end 的地方做補全。

padStart 方法

// Syntax:str.padStart(targetLength [, padString])

'o'.padStart(5, 'Hell'); // Hello

padEnd 方法

// Syntax:str.padEnd(targetLength [, padString])

'123'.padEnd(6, 'x'); // 123xxx

Template Strings

終於來到我們最常使用的 Template String 啦!

我們以前可能都是這樣輸出 HTML template 的:

const t = 'My name is <b>' + name + '</b>, Nice to meet you'; // 不易閱讀!

Template Strings - Example 1:

const name = 'PJ';
const t = `My name is <b>${name}</b>, Nice to meet you`; // 變數的部份寫在 `${}` 內來顯示

Template Strings - Example 2:

const t1 = `Hello\nWorld`;
const t2 = `Hello, World
Hello ECMAScript 6
`;

console.log(t1); // 透過 \n 做換行
console.log(t2); // 換行

超方便的!

也可以用在 HTML 的 style 設定:

const style = {
    color: 'red',
    size: 4
};
let temp = `
    <span>
        <font size="${style.size}" color="${style.color}">Hi!</font>
    </span>
`;

console.log(temp);

Tagged template literals

function 可以處理跟在後面的 template strings:

function tag(str, ...values) {
  console.log(str);
  console.log(values[0]);
  console.log(values[1]);
}

const a = 5;
const b = 10;

tag`I have ${a} and ${b} number.`

// result =>
// [I have, and, number.]
// 5
// 10

raw 方法

raw 是 ES6 String 原生的方法,可以用來處理 template stirngs:

const text = String.raw`ECMAScript 6: \n`;
console.log(text === 'ECMAScript 6: \\n') // true

Reference