说起国际化,开发过跨区域网页的小伙伴应该都遇到过。我们的网页需要配置多套语言,方便用户进行切换。
本文就以 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