字串模板的進階用法 tagged-template

第一次知道!

簡述

ES6 中的「template string」除了最原本的字串拼接用途以外,它還能用來 trigger function,用法是這樣子:

1
console.log`hello` // ['hello']

放在裡面的東西會被轉成 Array 再傳入進去,這是第一種用法。

第二種用法是加上 ${...},它的行為比較特別一點,邊看例子邊解釋:

1
2
const name = 'peanu'
console.log`hello ${name}` // ['hello ', ''] peanu

簡單來說,沒有用 ${...} 包住的內容會被用 Array 來包裝,而 ${...} 的部分會被放到後面去。(關於 Array 裡的空字串,你只要記得每當出現 ${...} 的地方後面都會自動補一個空字串。這個行為會讓我們用起來比較方便,不用太執著原因。)

OK,你可能會想說這可以做啥?讓我再舉個例子:

1
2
3
4
5
6
7
8
9
10
// ...運算子會把剩下的 params 變成 array
function saySometing(a, ...b) {
console.log('a: ', a)
console.log('b: ', b)
}

const name = 'peanu'
const msg = 'how are you'
const time = 'today'
saySometing`hello ${name}, ${msg}, ${time}`

發現了嗎?透過這種方式我就可以把參數拆成兩個部分,一個是純字串,一個是 ${...}

所以呢,用這招我就可以做出一個用來「過濾惡意字串(XSS)」的 function:

1
2
3
4
5
6
7
8
9
10
11
12
13
function safeHTML(template, ...unsafe) {
// 在 template[0] 跟 template[i+1] 之間 join 不安全字串
let result = template[0]
for (let i = 0; i < unsafe.length; i++) {
result += unsafe[i].replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
result += template[i + 1]
}
return result
}

const unsafe = `<script>alert(1)</script>`
let message = safeHTML`<p>${unsafe} has ${unsafe} sent you a message.</p>`
console.log(message)

總之只是想介紹一下這種 trigger function 的另外一種用途,這也是 style component 的執行原理。

mentor-program-day110 關於 Express 中的 session-secret
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×