QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 2180|回复: 0

[HTML/CSS/JS] 闭包除了用作缓存,还有哪些功能?

[复制链接]

等级头衔

积分成就    金币 : 2841
   泡泡 : 1516
   精华 : 6
   在线时间 : 1294 小时
   最后登录 : 2024-11-21

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老

联系方式
发表于 2021-2-4 12:09:15 | 显示全部楼层 |阅读模式
1、返回值(最常用)+ v4 }. Y/ N# S4 J3 {. W
  1. //1.返回值 最常用的
  2.     function fn(){
  3. var name="hello";
  4.         return function(){
  5.             return name;
  6.         }
  7.     }
  8. var fnc = fn();
  9.     console.log(fnc())//hello
      这个很好理解就是以闭包的形式将 name 返回。
8 G  m0 @" V- b( c) J4 t9 w; a2、函数赋值
6 j3 ?% B7 a6 O' g3 [* L$ _* _$ @1 X
  1. var fn2;
  2. function fn(){
  3.     var name="hello";
  4.     //将函数赋值给fn2
  5.     fn2 = function(){
  6.         return name;
  7.     }
  8. }
  9. fn()//要先执行进行赋值,
  10. console.log(fn2())//执行输出fn2
      在闭包里面给fn2函数设置值,闭包的形式把name属性记忆下来,执行会输出 hello。/ F: n; T+ L$ _. K+ l2 {, O
3、函数参数$ j7 F" E% r$ ?
  1. function fn(){
  2.     var name="hello";
  3.     return function callback(){
  4.         return name;
  5.     }
  6. }
  7. var fn1 = fn()//执行函数将返回值(callback函数)赋值给fn1,
  8. function fn2(f){
  9.     //将函数作为参数传入
  10.     console.log(f());//执行函数,并输出
  11. }
  12. fn2(fn1)//执行输出fn2
      用闭包返回一个函数,把此函数作为另一个函数的参数,在另一个函数里面执行这个函数,最终输出 hello
' G: n: M$ O& p- o+ j: R* `+ Q, T( h4、IIFE(自执行函数)
  1. (function(){
  2.         var name="hello";
  3.         var fn1= function(){
  4.             return name;
  5.         }
  6.         //直接在自执行函数里面调用fn2,将fn1作为参数传入
  7.         fn2(fn1);
  8.     })()
  9.     function fn2(f){
  10.         //将函数作为参数传入
  11.         console.log(f());//执行函数,并输出
  12.     }
      直接在自执行函数里面将封装的函数fn1传给fn2,作为参数调用同样可以获得结果 hello。
0 _+ E" D& |6 N, {0 M: i6 J0 a9 j8 s5、循环赋值* f* |" f: i" c8 r; s
  1. //每秒执行1次,分别输出1-10
  2. for(var i=1;i<=10;i++){
  3.     (function(j){
  4.         //j来接收
  5.         setTimeout(function(){
  6.             console.log(j);
  7.         },j*1000);
  8.     })(i)//i作为实参传入
  9. }
      如果不采用闭包的话,会有不一样的情况。
- g5 o/ B8 p7 Z) \4 [. f" Y6、getter和setter9 n! X; i  b' V; R
  1. function fn(){
  2.         var name='hello'
  3.         setName=function(n){
  4.             name = n;
  5.         }
  6.         getName=function(){
  7.             return name;
  8.         }
  9.         //将setName,getName作为对象的属性返回
  10.         return {
  11.             setName:setName,
  12.             getName:getName
  13.         }
  14.     }
  15.     var fn1 = fn();//返回对象,属性setName和getName是两个函数
  16.     console.log(fn1.getName());//getter
  17.         fn1.setName('world');//setter修改闭包里面的name
  18.     console.log(fn1.getName());//getter
      第一次输出 hello 用setter以后再输出 world ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。
4 w( c# O- W  I. P7、迭代器(执行一次函数往下取一个值). {* {* N% N9 z# c
  1. var arr =['aa','bb','cc'];
  2. function incre(arr){
  3.     var i=0;
  4.     return function(){
  5.         //这个函数每次被执行都返回数组arr中 i下标对应的元素
  6.          return arr[i++] || '数组值已经遍历完';
  7.     }
  8. }
  9. var next = incre(arr);
  10. console.log(next());//aa
  11. console.log(next());//bb
  12. console.log(next());//cc
  13. console.log(next());//数组值已经遍历完
8、首次区分(相同的参数,函数不会重复执行)* g* K9 Q0 Q! ~1 X9 ~
  1. var fn = (function(){
  2.                var arr=[];//用来缓存的数组
  3.                    return function(val){
  4.                        if(arr.indexOf(val)==-1){//缓存中没有则表示需要执行
  5.                            arr.push(val);//将参数push到缓存数组中
  6.                            console.log('函数被执行了',arr);
  7.                            //这里写想要执行的函数
  8.                        }else{
  9.                            console.log('此次函数不需要执行');
  10.                        }
  11.                        console.log('函数调用完打印一下,方便查看已缓存的数组:',arr);
  12.                    }
  13.                })();
  14.        fn(10);
  15.        fn(10);
  16.        fn(1000);
  17.        fn(200);
  18.        fn(1000);
执行结果如下:
* x4 l" c# l5 n6 x" n8 w: B  L: X 1.jpg
* A& y* Q6 a( f' S9 V- A( S       可以明显的看到首次执行的会被存起来,再次执行直接取。- J/ F+ x+ B: k) h
9、缓存
2 l" Z0 f! u7 h
  1. //比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算
  2.      var fn=(function(){
  3.         var cache={};//缓存对象
  4.         var calc=function(arr){//计算函数
  5.             var sum=0;
  6.             //求和
  7.             for(var i=0;i<arr.length;i++){
  8.                 sum+=arr[i];
  9.             }
  10.             return sum;
  11.         }
  12.         return function(){
  13.             var args = Array.prototype.slice.call(arguments,0);//arguments转换成数组
  14.             var key=args.join(",");//将args用逗号连接成字符串
  15.             var result , tSum = cache[key];
  16.             if(tSum){//如果缓存有   
  17.                 console.log('从缓存中取:',cache)//打印方便查看
  18.                 result = tSum;
  19.             }else{
  20.                 //重新计算,并存入缓存同时赋值给result
  21.                 result = cache[key]=calc(args);
  22.                 console.log('存入缓存:',cache)//打印方便查看
  23.             }
  24.             return result;
  25.         }
  26.      })();
  27.     fn(1,2,3,4,5);
  28.     fn(1,2,3,4,5);
  29.     fn(1,2,3,4,5,6);
  30.     fn(1,2,3,4,5,8);
  31.     fn(1,2,3,4,5,6);
输出结果:! O. R% p( V' q( {* f% T
2.jpg ) R* S+ z  L0 e9 `$ a) r
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-11-22 02:36

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表