[toc]
## unicode編碼
JavaScript使用unicode編碼,可以識別\u0000到\uFFFF之間的字符,如果超出這個字符則必須要使用兩個雙字節的形式表達。
比如如果一個字符超出0xFFFF,在ES5中會被截斷:
```js
\u20BB7會被理解成\u20BB+7
```
在ES6中支持對超出0xFFFF的字符的解析,使用{}括起來即可:
```js
\u{20BB7};
"\u{1F680}" === "\uD83D\uDE80"; //true,表示大括號標記法與四字節的UTF-16編碼等價
```
## 字符串新特性
### codePointAt
在JavaScript內部,字符以UTF-16格式存儲,每個字符為2個字節,對于使用4個字節存儲的字符會誤認為其是2個字節。
codePointAt是string.charCodeAt的改進版,charCodeAt方法不能正確識別4個字節的字符。
```
//ES5
var s = "吉"
s.length; //2
s.charCodeAt(0); //55362,只讀取了兩個字節
s.charCodeAt(1); //57271
//ES6
var s = "吉a"
s.length; //2
s.codePointAt(0); //134071,正確讀取了4個字節
s.codePointAt(1); //57271
s.codePointAt(2); //97
```
可以用來判斷你一個字符是由幾個字符組成,判斷碼點與0xFFFF的關系。
### String.fromCodePoint
ES5中的String.fromCharCode方法可以返回指定碼點的字符。但是不能識別4個字節的字符。
```
//ES5
String.fromCharCode(0x20BB7); //"(不知道是啥)"
//ES6
String.fromCodePoint(0x20BB7); //"吉"
```
如果String.fromCharPoint()有多個參數則將其對應的字符拼接起來返回
### 字符串遍歷
ES6為字符串添加了遍歷接口,可以使用for..of遍歷,最大的優點是可以識別碼點大于0xFFFF的字符
```
for(let codePoint of "foo"){
console.log(codePoint);
}
//"f" "o" "o"
```
### at()
ES5提供了charAt()方法用來返回字符串指定位置的字符,但是不能識別4個字節的字符。
ES6提供了at()方法可以正確的識別4個字節的字符
```
//ES5
"abc".charAt(0); //"a"
"吉利".charAt(0); //"\uD842"
//ES6
"abc".at(0); //"a"
"吉".at(0); //"吉"
```
### includes,startsWith,endsWith
在ES5中只能通過indexOf方法來判斷字符串中是否包含另一個字符串
ES6提供了三種方法,都返回布爾值:
- includes()
- startsWith()
- endsWith()
### repeat(n)方法
將一個字符串重復n次:
```
"hello".repeat(2); //"hellohello"
```
如果n為小數則取整,如果n為負值或其他非法值則出錯。
### padStart(),padEnd()
ES6推出的字符串自動補全長度的功能。
```
"x".padStart(5,"ab"); //"ababx"
"x".padStart(4,"ab"); //"abax"
"x".padEnd(5,"ab"); //"xabab"
"x".padEnd(4,"ab"); //"xaba"
```
如果指定的長度小于等于原字符串,則什么都不做,如果省略第二個字符串,則默認使用空格補齊:
```
"x".padStart(5); //" x"
```
### 模板字符串
模板字符串使用`...`形式,要使用(`)引起來以區分普通字符串和模板字符串。
模板字符串中的變量使用${變量名}表示。
```
var name = "wxs",
age = "24";
`hello ${name},your age is ${age}`
```
如果字符串中包含(`)則要使用(`\`)來轉義
在${}中可以放置任意的JavaScript表達式,比如運算和對象屬性等。還能調用函數:
```
function f(){
return "world";
}
`hello ${f()}`
```
### String.raw()
ES6添加了String的raw方法,用來返回一個模板被替換的字符串。
```
String.raw(`Hi\n${2+3}!`);
//"Hi\\n5!",注意轉義符前添加了一個\
如果原字符串中的轉義符已經被轉義,則不做處理
String.raw(`Hi\\n`)
//"Hi\\n"
```