說起國際化,開發過跨區域網頁的小伙伴應該都遇到過。我們的網頁需要配置多套語言,方便用戶進行切換。 本文就以 React 為例,介紹其中一種實現方案,並學習一下其中的知識點。 一種國際化方案 方案是這樣的: 為多套語言創建對應的 object,並 export 出去 通過 js 立即執行函數,載入選定 ...
說起國際化,開發過跨區域網頁的小伙伴應該都遇到過。我們的網頁需要配置多套語言,方便用戶進行切換。
本文就以 React 為例,介紹其中一種實現方案,並學習一下其中的知識點。
一種國際化方案
方案是這樣的:
-
為多套語言創建對應的 object,並 export 出去
-
通過 js 立即執行函數,載入選定語言 js 文件中的 object,並 export 出去
-
項目中引入第 2 步中 export 的 object,直接使用即可
圖示(假設支持中英兩種語言):
![](https://static001.geekbang.org/infoq/dd/dd750132c6a65897a57f3d97deb9cdaf.png)
加上業務文件引用後,全景圖如下:
![](https://static001.geekbang.org/infoq/94/944406a6e709b9240fb2e0902047891c.png)
可以看出來,其實 lang/index.js 文件起到了一種「介面」的作用,幫我們屏蔽了語言類型。在實際情況中,我們可以讓瀏覽器自動獲取特定 cookie,並藉助 js 立即執行函數,將對應的語言包 object 暴露出去,此時業務代碼中引用的地方就可以自動獲取到對應的語言,進而展示:
![](https://static001.geekbang.org/infoq/d3/d38d5e5b24f08d7a545499388117f5bc.png)
你看,這種方案是不是超級簡單?
下麵我們來看看其中涉及到的一個重要知識點:立即執行函數。
什麼是立即執行函數?
-
首先,它是一個匿名函數;
-
其次,它在聲明後會被立即執行;
-
最後,使用圓括弧加以調用。
這就是它的最簡定義了。
我們把上面用到的代碼簡化一下:
![](https://static001.geekbang.org/infoq/69/691b55ab70f3df4567ffe5220237ff65.png)
在 js 中,function 這個關鍵字,既可以當做語句,也可以當做表達式,上面立即執行函數的寫法,其實就是把 function 當作表達式了。
插入一個關鍵知識:
![](https://static001.geekbang.org/infoq/ff/ff6fb67269403b9bf9ce939843131ea9.png)
如何讓 function 當作表達式呢?我們看下 JS 引擎的規定:如果 function 出現在行首,則解析成語句。對於語句來說,不能以圓括弧結尾,否則報錯。
所以,只要想辦法讓 function 被解析為表達式,就可以得到 立即執行函數的多種寫法,我們總結一下:
![](https://static001.geekbang.org/infoq/00/006af9785e6ecb9d193e6b9bafb0b346.png)
註 1:圖中展示的是無參形式,也可以存在形參和實參。
可以看出,不同形式的寫法,具有不同的返回值。在本文的國際化例子中,我們在方法體中 return 了語言包 object,並不關心函數的返回值,所以可以隨意使用任意寫法:
![](https://static001.geekbang.org/infoq/1a/1a319b752e07e6e3eb6c948184f9b970.png)
那麼問題來了,立即執行函數有啥用武之地?
立即執行函數的幾大作用
-
使用匿名函數,無需為函數命名,避免污染全局變數
-
它的內部形成了一個單獨的作用域,可以封裝外部無法讀取的私有變數
第一點很好理解,我們看看第二點在說什麼。
繼續用國際化的例子說明,我們其實把 cookie 封閉在了 lang/index.js 文件中,外部文件是無法讀取到這個 LocaleCode 這個私有變數的(其實也根本不關心),這就是所謂的封裝帶來的安全性。
擴展到高階函數
作為 js 中的一等公民,函數不僅擁有一切傳統函數的使用方式(聲明和調用),而且可以做到像簡單值一樣賦值、傳參、返回。所以我們完全可以讓立即函數返回一個函數,舉個例子:
![](https://static001.geekbang.org/infoq/be/be5bf88aa8ef7dc14b6893a4d137c2fb.png)
看一下執行結果,就很好理解了:
![](https://static001.geekbang.org/infoq/e7/e783f908b7f5e79ae06c9c1ea6776a7c.png)
所以,你可以盡情把高階函數的能力帶到立即執行函數中。
一句話總結:立即執行函數的作用域封閉能力可以很優雅地實現一些現實業務訴求,還可以結合高階函數實現更為複雜的功能,希望大家都能靈活掌握並運用。
最後,本文部分內容參考了文章:https://www.jianshu.com/p/b10b6e93ddec,推薦一讀。
TRANSLATE with