QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 2179|回复: 0

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

[复制链接]

等级头衔

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

丰功伟绩

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

联系方式
发表于 2021-2-4 12:09:15 | 显示全部楼层 |阅读模式
1、返回值(最常用), _& W) N. n; s4 M
  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 返回。7 Q! i& V, e- l: p& Q7 N# B# k
2、函数赋值, I0 y$ G, v- R  g
  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。
! V7 j6 {; E  l; u  ~3、函数参数
4 e' s& `1 n, B5 b6 L* |. d
  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
. r$ }) }7 R0 }. X8 Z8 v4、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。
8 e+ s) \3 J1 ^  q& |5、循环赋值
% |( |. J+ P8 a! E1 }
  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. }
      如果不采用闭包的话,会有不一样的情况。
  w' j8 r% j  L9 l2 [8 f) a, ?6、getter和setter# j5 C7 T% c  j' e9 p9 f4 L
  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 ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。
' ^$ K3 ~5 }# x& F7、迭代器(执行一次函数往下取一个值)1 s8 |3 b; g/ p) |/ |) T% v- G
  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、首次区分(相同的参数,函数不会重复执行)
/ K" O. t9 C8 v
  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);
执行结果如下:# X- Y2 c, E! d+ Y& e2 N
1.jpg
& G1 g3 g( L' x* Z       可以明显的看到首次执行的会被存起来,再次执行直接取。% h$ o# z2 e( K" g% U6 Y
9、缓存
( P) N4 p, C* i/ ^
  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);
输出结果:7 s$ Q* E9 B- ~( k4 W
2.jpg : v5 X) v* w1 M# B* F5 X: @
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by paopaomj X3.5 © 2016-2025 sitemap

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