帮你精通JS:一段函数的进化史

开发 前端
我们以memorization的方式求factorial而遭遇over-exposure的问题,由此引出priciple-of-lease-exposure的原则。作为解决方案,直觉的做法是将其包裹在外层函数之内,不足之处在于需要重新declare函数。进一步解决问题,省略掉重新declare与assignment,用IIFE,在定义的同时也实现定义。

[[391818]]

一、首先写一段求阶乘的函数

用 memozation实现一段factorial

  1. > var cache = {}; 
  2. function factorial(x) { 
  3. ...     if (x < 2) return 1; 
  4. ...     if (!(x in cache)) { 
  5. .....         cache[x] = x * factorial(x - 1); 
  6. .....     } 
  7. ...     return cache[x]; 
  8. ... } 
  9. > factorial(8) 
  10. 40320 
  11. > cache 
  12. '2': 2, '3': 6, '4': 24, '5': 120, '6': 720, '7': 5040, '8': 40320 } 

此处 cache 只用于函数 factorial 之内,却过分暴露于外。按照 least exposure(POLE) 将其隐藏起来。直觉方法就是直接将其放入其中。

二、初步解决接口过分暴露的问题

重新定义最外层coverTheCache函数将其包裹起来。

  1. function coverTheCache() { 
  2. ...     // "middle scope"where we cover `cache` 
  3. ...     var cache = {}; 
  4. ... 
  5. ...     return factorial; 
  6. ... 
  7. ...     // ********************** 
  8. ... 
  9. ...     function factorial(x) { 
  10. ...         // inner scope 
  11. ...         if (x < 2) return 1; 
  12. ...         if (!(x in cache)) { 
  13. .....             cache[x] = x * factorial(x - 1); 
  14. .....         } 
  15. ...         return cache[x]; 
  16. ...     } 
  17. ... } 

运行测试:

  1. > let factorial2 = coverTheCache(); 
  2. > factorial2(9) 
  3. 362880 
  4. > factorial(10) 
  5. 3628800 

此解决方案完全符合直觉,就是单单的将步骤一中的factorial函数与变量cache收纳到另外一个函数coverTheCache的肚子里,包裹了一层环境。

缺憾之处在于,`let factorial2 = hideTheCache();`此处还要另行调用。因此,接下来将重新declare与赋值的这一步去掉。

三、IIFE解决过分暴露的问题

  1. > const factorial3 = (function coverTheCache() { 
  2. ...     var cache = {}; 
  3. ... 
  4. ...     function factorial(x) { 
  5. ...         if (x < 2) return 1; 
  6. ...         if (!(x in cache)) { 
  7. .....             cache[x] = x * factorial(x - 1); 
  8. .....         } 
  9. ...         return cache[x]; 
  10. ...     } 
  11. ... 
  12. ...     return factorial; 
  13. ... })(); // 关键步骤 
  14. undefined 
  15. > factorial3(11) 
  16. 39916800 
  17. > factorial(300) 
  18. Infinity 
  19. > factorial(30) 
  20. 2.6525285981219103e+32 

如此就不必再另行一步调用,该方法称之为 IIFE(

Immediately-Invoked-Function-Expression):

  1. // outer scope 
  2. (function(){ 
  3.     // inner hidden scope 
  4. })(); 
  5. // more outer scope 

四、总结

我们以memorization的方式求factorial而遭遇over-exposure的问题,由此引出

priciple-of-lease-exposure的原则。

作为解决方案,直觉的做法是将其包裹在外层函数之内,不足之处在于需要重新declare函数。进一步解决问题,省略掉重新declare与assignment,用IIFE,在定义的同时也实现定义。

以上就是factorial这个函数进化的三个步骤。

 

责任编辑:姜华 来源: 今日头条
相关推荐

2011-12-21 16:44:00

信息图手机进化史

2014-09-01 16:29:34

2018-08-22 17:58:01

数据平台数据仓库架构

2011-09-01 09:34:21

架构

2011-11-03 15:25:07

Android

2010-07-27 14:04:52

2011-11-29 09:54:20

Google进化史

2023-04-13 13:25:40

ChatGPTGPT神经网络

2010-10-09 14:46:20

2018-03-23 12:20:25

数据中心网络数据

2013-06-24 09:18:05

2010-04-07 14:54:20

Unix操作系统

2016-02-04 09:17:59

2023-11-27 09:23:19

2022-03-25 14:01:20

元宇宙虚拟世界进化

2010-01-21 16:08:26

C++语言

2022-03-29 09:35:15

FirefoxUI浏览器

2019-06-19 15:54:12

Redis缓存内存

2011-11-04 15:58:52

手机操作系统进化史

2014-08-13 10:31:26

Windows操作系统
点赞
收藏

51CTO技术栈公众号