字符串拓展
Unicode 相關
- JS 允許使用
/uxxxx
的Unicode方式顯示字符, 但是只限于碼點在/u0000~/uFFFF之間, 超過該范圍的碼點必須用雙字節形式表示 - ES6 中, 將碼點放入大括號內, 就可以解讀
- JS 不能處理4個字節的字符, 字符串長度會被誤判為2
- ES6 提供了
codePointAt
方法, 能夠正確處理 4 個字節儲存的字符 - 但是該方法在返回 4 個字節的字符串時, 依舊會返回兩個參數, 第一個為正確解讀的碼點, 第二個為后兩個字節的碼點, 所以在多個包含 4 個字節的字符串時, 需要使用
for...of
循環 - 同樣的, 將 4 個字節的碼點轉換成字符串, ES6 提供了
String.fromCodePoint()
方法
字符串操作
- ES6 為字符串添加了遍歷器接口, 使其可以被
for...of
循環遍歷, 相對傳統的for
, 其優勢在于可以識別大于/uFFFF
的碼點
includes(), startsWith(), endsWith()
這三個方法可以確定字符串是否包含在另一個字符串中
includes()
方法表示是否找到了參數字符串.startsWith()
方法表示參數字符串是否為原字符串的首位endsWith()
方法表示參數字符串是否為原字符串的尾位- 三個方法的第一個參數為匹配字符串
- 前兩個方法第二個參數為起始搜索位置(從 0 開始)
endsWith()
方法第二個參數為原字符串從左到右截取后剩下的長度
let s = 'Hello world!';s.startsWith('world', 6) // true s.endsWith('Hello', 5) // true s.includes('Hello', 6) // false
repeat()
repeat()
方法返回一個新字符串, 其接收一個number
類型參數, 表示重復次數- 該參數不能為小于等于 -1 的負數或者
Infinity
- 如果負數大于 -1, 則視為0
- 如果是字符串, 則會先轉換為數字
- 其他的均視為0
'x'.repeat(3) // "xxx"
- 該參數不能為小于等于 -1 的負數或者
padStart(), padEnd()
這兩個方法用于補全字符串
當字符串長度不夠指定長度時, 會在頭部或尾部補全
該方法接收兩個參數
- 第一個是指定字符串長度,
- 第二個是用來補全的字符串, 該參數不填默認為空格
當字符串長度加上補全字符串超過指定長度時, 將截取超出位數的補全字符串
該方法一般用在數值補全指定位數
'1'.padStart(10, '0') // "0000000001" '12'.padStart(10, '0') // "0000000012" '123456'.padStart(10, '0') // "0000123456"
模板字符串相關
基本用法
語法
- 模板字符串定義在兩個反引號( ` )之間,
- 它可以當做普通字符串使用, 也可以定義多行字符串, 或者在字符串中嵌入變量
- 變量寫在
${}
之中, 除了能調用變量還能引用對象屬性, 函數和進行簡單的運算 - 如果需要使用反引號, 則需要用反斜杠 ?轉義
- 模板字符串默認會保留空格與換行, 如果不需要可以用
trim()
方法消除
$('#result').append(`There are <b>${basket.count}</b> itemsin your basket, <em>${basket.onSale}</em>are on sale! `);
標簽模板
模板字符串還可以當做模板標簽
當模板字符串里為不包含變量的簡單字符串, 數字等時, 函數會將模板字符串當做參數來處理
- 該用法不能代替原來函數的調用方式, 這里只是介紹使用方法, 原因在下面解釋
alert`'abc'123` // 'abc'123
當模板字符串里包含變量時, 會有以下解析
將被變量( 即
${}
標識 )分開的普通字符串放進數組并當做第一個參數變量被從左到右依次解析并依次放入第二, 第三...第n個參數
tag`Hello ${ a + b } world ${ a * b }`; // 相當于 tag(['Hello ', ' world ', ''], 15, 50);
需要注意的是, 使用這種傳參方式
- 第一個參數永遠是數組
- 數組里有一個
raw
屬性, 該屬性保存的是轉義后的原字符串, 所以該方式不能取代傳統函數調用方式 - 數組里的元素個數永遠等于參數個數
- 函數參數至少為兩個(數組元素同), 如果只傳一個變量, 則數組的兩個元素為空
- 如果用這種方式傳遞字符串, 必須包含在單引號 ( ' )內, 否則會當做變量處理
- 通常這樣做函數只聲明一個參數, 傳遞的變量通過
arguments
方法來拿
下面一個復雜的案例可以涵蓋以上內容
let total = 30; let msg = passthru`The total is ${total} (${total*1.05} with tax)`;function passthru(literals) {let result = '';let i = 0;// 這里 literals 與 arguments 長度一致while (i < literals.length) {// 這里 i++ 是使下面 arguments 直接從第二個參數拿起result += literals[i++];if (i < arguments.length) {result += arguments[i];}}return result; }msg // "The total is 30 (31.5 with tax)"
通常標簽模板重要應用是用來過濾 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, "&").replace(/</g, "<").replace(/>/g, ">");// Don't escape special characters in the template.s += templateData[i];}return s; }let sender = '<script>alert("abc")</script>'; // 惡意代碼 let message = SaferHTML`<p>${sender} has sent you a message.</p>`;console.log(message) // <p><script>alert("abc")</script> has sent you a message.</p>
其他的需要過濾轉換的都可以使用標簽模板