<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JS閉包的9大經(jīng)典使用場景

          共 5831字,需瀏覽 12分鐘

           ·

          2021-06-19 13:24

          作者:fly63

          http://www.fly63.com/article/detial/9974

          1.返回值(最常用)

          //1.返回值 最常用的
          function fn(){
              var name="hello";
              return function(){
                  return name;
              }
          }
          var fnc = fn();
          console.log(fnc())//hello

          這個很好理解就是以閉包的形式將 name 返回。

          2.函數(shù)賦值

          var fn2;
          function fn(){
              var name="hello";
              //將函數(shù)賦值給fn2
              fn2 = function(){
                  return name;
              }
          }
          fn()//要先執(zhí)行進行賦值,
          console.log(fn2())//執(zhí)行輸出fn2

          在閉包里面給fn2函數(shù)設(shè)置值,閉包的形式把name屬性記憶下來,執(zhí)行會輸出 hello。

          3.函數(shù)參數(shù)

          function fn(){
              var name="hello";
              return function callback(){
                  return name;
              }
          }
          var fn1 = fn()//執(zhí)行函數(shù)將返回值(callback函數(shù))賦值給fn1,
           
          function fn2(f){
              //將函數(shù)作為參數(shù)傳入
              console.log(f());//執(zhí)行函數(shù),并輸出
          }
          fn2(fn1)//執(zhí)行輸出fn2

          用閉包返回一個函數(shù),把此函數(shù)作為另一個函數(shù)的參數(shù),在另一個函數(shù)里面執(zhí)行這個函數(shù),最終輸出 hello

          4.IIFE(自執(zhí)行函數(shù))

          (function(){
              var name="hello";
              var fn1= function(){
                  return name;
              }
              //直接在自執(zhí)行函數(shù)里面調(diào)用fn2,將fn1作為參數(shù)傳入
              fn2(fn1);
          })()
          function fn2(f){
              //將函數(shù)作為參數(shù)傳入
              console.log(f());//執(zhí)行函數(shù),并輸出
          }

          直接在自執(zhí)行函數(shù)里面將封裝的函數(shù)fn1傳給fn2,作為參數(shù)調(diào)用同樣可以獲得結(jié)果 hello

          5.循環(huán)賦值

          //每秒執(zhí)行1次,分別輸出1-10
          for(var i=1;i<=10;i++){
              (function(j){
                  //j來接收
                  setTimeout(function(){
                      console.log(j);
                  },j*1000);
              })(i)//i作為實參傳入
          }

          如果不采用閉包的話,會有不一樣的情況。

          6.getter和setter

          function fn(){
              var name='hello'
              setName=function(n){
                  name = n;
              }
              getName=function(){
                  return name;
              }

              //將setName,getName作為對象的屬性返回
              return {
                  setName:setName,
                  getName:getName
              }
          }
          var fn1 = fn();//返回對象,屬性setName和getName是兩個函數(shù)
          console.log(fn1.getName());//getter
          fn1.setName('world');//setter修改閉包里面的name
          console.log(fn1.getName());//getter

          第一次輸出 hello 用setter以后再輸出 world ,這樣做可以封裝成公共方法,防止不想暴露的屬性和函數(shù)暴露在外部。

          7.迭代器(執(zhí)行一次函數(shù)往下取一個值)

          var arr =['aa','bb','cc'];
          function incre(arr){
              var i=0;
              return function(){
                  //這個函數(shù)每次被執(zhí)行都返回數(shù)組arr中 i下標對應的元素
                   return arr[i++] || '數(shù)組值已經(jīng)遍歷完';
              }
          }
          var next = incre(arr);
          console.log(next());//aa
          console.log(next());//bb
          console.log(next());//cc
          console.log(next());//數(shù)組值已經(jīng)遍歷完

          8.首次區(qū)分(相同的參數(shù),函數(shù)不會重復執(zhí)行)

          var fn = (function(){
           var arr=[];//用來緩存的數(shù)組
           return function(val){
               if(arr.indexOf(val)==-1){//緩存中沒有則表示需要執(zhí)行
                   arr.push(val);//將參數(shù)push到緩存數(shù)組中
                   console.log('函數(shù)被執(zhí)行了',arr);
                   //這里寫想要執(zhí)行的函數(shù)
               }else{
                   console.log('此次函數(shù)不需要執(zhí)行');
               }
               console.log('函數(shù)調(diào)用完打印一下,方便查看已緩存的數(shù)組:',arr);
           }
          })();

          fn(10);
          fn(10);
          fn(1000);
          fn(200);
          fn(1000);

          執(zhí)行結(jié)果如下:
          可以明顯的看到首次執(zhí)行的會被存起來,再次執(zhí)行直接取。

          9.緩存

          /比如求和操作,如果沒有緩存,每次調(diào)用都要重復計算,采用緩存已經(jīng)執(zhí)行過的去查找,查找到了就直接返回,不需要重新計算    
          var fn=(function(){
            var cache={};//緩存對象
            var calc=function(arr){//計算函數(shù)
                var sum=0;
                //求和
                for(var i=0;i<arr.length;i++){
                    sum+=arr[i];
                }
                return sum;
            }

            return function(){
                var args = Array.prototype.slice.call(arguments,0);//arguments轉(zhuǎn)換成數(shù)組
                var key=args.join(",");//將args用逗號連接成字符串
                var result , tSum = cache[key];
                if(tSum){//如果緩存有   
                    console.log('從緩存中取:',cache)//打印方便查看
                    result = tSum;
                }else{
                    //重新計算,并存入緩存同時賦值給result
                    result = cache[key]=calc(args);
                    console.log('存入緩存:',cache)//打印方便查看
                }
                return result;
            }
          })();
          fn(1,2,3,4,5);
          fn(1,2,3,4,5);
          fn(1,2,3,4,5,6);
          fn(1,2,3,4,5,8);
          fn(1,2,3,4,5,6);

          輸出結(jié)果:

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美在线免费播放不卡欧美 | 在线v片 | 高清无码视频在线免费看 | 在线你懂得| 青娱乐99 |