不用括號也能呼叫? 設計一個接受模板字符串的函數吧! JavaScript
若你用過 styled-component ,肯定常把一長串的 CSS 放在 ` ` 之間,並且沒有包覆在 ( ) 裡頭,那函數是如何接收的呢?
讓我們一起來研究並設計一個接收模板字符串的函數!
文末 我會撰寫了一個與 styled 接受形式相仿的簡單小函數,依照 props value 決定 background-color 要 blue 還是 pink 。
我是萌新,什麼是 styled-component ?
styled-component 是一個允許你在模板字符裡頭輸入 CSS ,並且幫你產生對應樣式的組件,在React、Vue都能夠使用(vue-styled-components)。
不過不用擔心,這篇並不是著重在 styled-component ,而是在這個一周有 67 萬下載量的函式庫中,追尋裡頭的魔法。
第一次嘗試
想要挖掘深一點,不要先尋找答案,而是先試試看?
讓我們來定義一個函數,並把它所有傳進來的參數都印出來看看?
function logAll(...args){
console.log('印個東西來瞧瞧!',args)
}logAll`hello!world`
來看看印出來的結果吧!
顯然後面的樣板字符串是真的能被函數所接收,而不用透過括號 () ,我們解決了一開始的問題,那我們再挖深一點,用樣板字符串的好處是什麼呢?為什麼不直接把樣板字符串像是變數一樣傳進去呢?
註:
function fn(…args)
的用法會把fn(1,2,3)
變成args[0]=1
、args[1]=2
、…,這種解構並且把參數變成陣列操作的用法非常方便,更詳細的函數解構設計請看這篇《解構賦值 — 設計函數時的小技巧 JavaScript》。
尋找真理
我們先依照關鍵字去搜尋…「模板字符串」、「樣板字符 函數 參數」、….等等,可以找到 MDN 上的文章。
前面在介紹模板字符的用法,比如可以在模板字符裡面插入變數…等等的。
var father = {name:'Dio',age:100};
var friend = {name:'Mista',age:19}// 以前古人的動態字串是這樣
console.log('我的爸爸叫做' + father.name + ',我的朋友叫做'+ friend.name);// 模板字符串允許你這麼做:
console.log(`我的爸爸叫做${father.name},我的朋友叫做 ${friend.name}`);
讓我們繼續往下看。
標籤樣板字面值
(讓我偷懶引用一下 MDN 上面的解釋)
標籤樣板字面值是一種更高級的樣板字面值形式,允許你透過標籤函數操作樣板字面值的輸出。
- 標籤函數的第一個參數是一字串陣列
- 其餘參數則是處理過的表達式
最終,你可以返回一個經處理後的字串,甚至是完全不一樣的東西。
由於我覺得MDN舉得例子有點落落長(例子很棒啦,但不適合 Medium 閱讀),我直接寫一個精簡版的例子。
隨便舉一個例子大概長這樣!
在 styled-component 的文檔中其實也有針對這種標籤樣板的函數用法做介紹,而且標題下的非常有趣《The magic behind 💅 styled-components》
這裡借用一張我覺得非常具象化的圖片。
一切都不是秘密
看來 styled-component
為什麼可以用 props
來決定如何改變樣式就不是什麼秘密了!
讓我們來寫一個可以接受參數的 CSS 吧!
尾聲
終於,我們不只搞懂了如何使用模板字串作為函數的輸入,而非天涯若比鄰的兩個括號 (………),而且也進一步搞懂了這樣傳遞參數後可以拿到不只字串本身,還能拿到表達式。
由於我在尋找這個答案時,當時用幾個關鍵字無從下手,所以請允許我用幾個 hash tag 總結一下這篇的關鍵字,方便探求答案的人能挖掘到這篇文章:
#JavaScript #模板字符串 #樣板字面值 #函數設計 #函數參數 #styled #styledcomponent #react #ES6
類似問題如下
JavaScript 函數如何接受模板字串?
JavaScript 函數設計 `` 反引號?
JavaScript 函數 沒有括號 styled
JavaScript tag function