帮你精通JS:一段函数的进化史
我们以memorization的方式求factorial而遭遇over-exposure的问题,由此引出priciple-of-lease-exposure的原则。作为解决方案,直觉的做法是将其包裹在外层函数之内,不足之处在于需要重新declare函数。进一步解决问题,省略掉重新declare与assignment,用IIFE,在定义的同时也实现定义。
- 作者:权哥编程来源:今日头条|2021-04-08 09:14
一、首先写一段求阶乘的函数
用 memozation实现一段factorial
- > var cache = {};
- >
- > function factorial(x) {
- ... if (x < 2) return 1;
- ... if (!(x in cache)) {
- ..... cache[x] = x * factorial(x - 1);
- ..... }
- ... return cache[x];
- ... }
- > factorial(8)
- 40320
- > cache
- { '2': 2, '3': 6, '4': 24, '5': 120, '6': 720, '7': 5040, '8': 40320 }
此处 cache 只用于函数 factorial 之内,却过分暴露于外。按照 least exposure(POLE) 将其隐藏起来。直觉方法就是直接将其放入其中。
二、初步解决接口过分暴露的问题
重新定义最外层coverTheCache函数将其包裹起来。
- > function coverTheCache() {
- ... // "middle scope", where we cover `cache`
- ... var cache = {};
- ...
- ... return factorial;
- ...
- ... // **********************
- ...
- ... function factorial(x) {
- ... // inner scope
- ... if (x < 2) return 1;
- ... if (!(x in cache)) {
- ..... cache[x] = x * factorial(x - 1);
- ..... }
- ... return cache[x];
- ... }
- ... }
运行测试:
- > let factorial2 = coverTheCache();
- > factorial2(9)
- 362880
- > factorial(10)
- 3628800
此解决方案完全符合直觉,就是单单的将步骤一中的factorial函数与变量cache收纳到另外一个函数coverTheCache的肚子里,包裹了一层环境。
缺憾之处在于,`let factorial2 = hideTheCache();`此处还要另行调用。因此,接下来将重新declare与赋值的这一步去掉。
三、IIFE解决过分暴露的问题
- > const factorial3 = (function coverTheCache() {
- ... var cache = {};
- ...
- ... function factorial(x) {
- ... if (x < 2) return 1;
- ... if (!(x in cache)) {
- ..... cache[x] = x * factorial(x - 1);
- ..... }
- ... return cache[x];
- ... }
- ...
- ... return factorial;
- ... })(); // 关键步骤
- undefined
- > factorial3(11)
- 39916800
- > factorial(300)
- Infinity
- > factorial(30)
- 2.6525285981219103e+32
如此就不必再另行一步调用,该方法称之为 IIFE(
Immediately-Invoked-Function-Expression):
- // outer scope
- (function(){
- // inner hidden scope
- })();
- // more outer scope
四、总结
我们以memorization的方式求factorial而遭遇over-exposure的问题,由此引出
priciple-of-lease-exposure的原则。
作为解决方案,直觉的做法是将其包裹在外层函数之内,不足之处在于需要重新declare函数。进一步解决问题,省略掉重新declare与assignment,用IIFE,在定义的同时也实现定义。
以上就是factorial这个函数进化的三个步骤。
【编辑推荐】
点赞 0
- 大家都在看
- 猜你喜欢
编辑推荐
- 24H热文
- 一周话题
- 本月获赞
- 太厉害了,终于有人能把TCP/IP协议讲的明明白白了!坐在马桶上看算法:快速排序花了一个星期,我终于把RPC框架整明白了!图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)开发 | 再见了,公司的“烂系统”6种微服务RPC框架,你知道几个?架构师的选择,Pulsar还是Kafka?终于有人把Elasticsearch原理讲透了!
- 太厉害了,终于有人能把TCP/IP协议讲的明明白白了!坐在马桶上看算法:快速排序花了一个星期,我终于把RPC框架整明白了!图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)6种微服务RPC框架,你知道几个?架构师的选择,Pulsar还是Kafka?五大自动化测试的Python框架终于有人把Elasticsearch原理讲透了!
- 太厉害了,终于有人能把TCP/IP协议讲的明明白白了!坐在马桶上看算法:快速排序花了一个星期,我终于把RPC框架整明白了!6种微服务RPC框架,你知道几个?图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)五大自动化测试的Python框架Java对象为啥要实现Serializable接口?Java 16 正式发布,已经是Java 8的两倍了
订阅专栏+更多
-
数据湖与数据仓库的分析实践攻略
助力现代化数据管理:数据湖与数据仓库的分析实践攻略共3章 | 创世达人7人订阅学习
-
云原生架构实践
新技术引领移动互联网进入急速赛道共3章 | KaliArch37人订阅学习
-
数据中心和VPDN网络建设案例
漫画+案例共20章 | 捷哥CCIE231人订阅学习
视频课程+更多
-
小程序项目实战【便签程序全栈开发!ThinkJS
讲师:杨过大侠392人学习过
-
MySQL数据库入门培训实战教程(从MySQL5.7 到
讲师:风哥120988人学习过
-
老汤大数据课程之 Hadoop 3
讲师:老汤1206人学习过
专题推荐+更多
-
订阅51CTO邮刊
点击这里查看样刊

51CTO服务号

51CTO官微