QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

泡泡马甲APP 更多内容请下载泡泡马甲手机客户端APP 立即下载 ×
查看: 2048|回复: 0

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

[复制链接]

等级头衔

积分成就    金币 : 2804
   泡泡 : 1516
   精华 : 6
   在线时间 : 1243 小时
   最后登录 : 2024-5-4

丰功伟绩

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

联系方式
发表于 2021-2-4 12:09:15 | 显示全部楼层 |阅读模式
1、返回值(最常用)7 m- U9 b" ?3 t
  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 返回。! O% B3 G% H9 p9 w3 R- r3 R9 S# _
2、函数赋值. M; p( p0 _% c) X/ ^- `( M
  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。1 ?& A' I4 t* R2 L' o5 l: _
3、函数参数, F9 ?: h7 m9 m4 f
  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
9 j7 q5 A% g" w1 f  U. J4、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。) H! y( W, y" u( O0 f) @0 B
5、循环赋值9 O/ {) x" F! }
  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. }
      如果不采用闭包的话,会有不一样的情况。
9 C/ F; S1 y! X( j, f6、getter和setter
0 Q. `6 X# @( c0 _0 N+ I- U. f# a$ }
  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 ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。& O  \5 C2 Q, a7 L
7、迭代器(执行一次函数往下取一个值)
) s8 C# [$ m% w% |) {5 v( c) j& `
  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、首次区分(相同的参数,函数不会重复执行)
+ t+ ^- Q$ q4 {5 }4 P
  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);
执行结果如下:
: P3 E9 H2 _1 J5 D* x 1.jpg
1 q# e$ X: @& d' a1 s
       可以明显的看到首次执行的会被存起来,再次执行直接取。9 u: @' j, ~' F. U! }& \) I
9、缓存
. k; d; E" E. W
  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) e. {+ |$ I 2.jpg
! X2 f1 Z2 R+ P. U# G7 z
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-5-4 10:15

Powered by paopaomj X3.4 © 2016-2024 sitemap

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