高阶函数和闭包

高阶函数

高阶函数是什么?

定义:高阶函数是对其他函数进行操作的函数,它接收函数作为参数或者将函数作为返回值输出

接收函数传给回调函数

例如:jquery
在这里插入图片描述

      <script>
          function fn(a,b,callback){
             console.log(a+b);
             //回调函数
             //函数传给collback
             callback&&callback();
          }
          fn(1,2,function(){
              console.log('我是最后调用的');
          });
      </script>

返回的是函数类型

      <script>
          function fn(){
           return function(){}
          }
          fn();
      </script>

原理是什么?

因为JavaScript中函数可以作为参数,同样可以作为返回值,可以传递给回调函数。

闭包(closure)

闭包的定义

定义:闭包指有权访问另一个函数作用域中变量的函数
简单地说:一个作用域可以访问另一个函数内部局部变量。

在这里插入图片描述
闭包:我们fun这个函数作用域访问了另外一个函数fn作用域的局部变量num
闭包函数:被访问的函数称为闭包函数

      <script>
          //闭包:我们fun这个函数作用域访问了另外一个函数fn作用域的局部变量num
          function fn(){
            var num=10;
            function fun(){
               console.log(num);
           }
           fun();
          }
          fn();
      </script>

调用过程?

  1. fn函数调用
  2. 到了num,此时没有值,为undefine
  3. 到了fun(),调用fun函数。
  4. 执行fun(){}函数,到了fun函数,此时有了闭包closure(fn)
  5. 访问fn的局部变量num

闭包的作用?

  1. fn外部作用域可以访问fun内部局部变量。函数外部作用域或者全局作用域可以访问局部变量。
  2. **延伸了变量的作用范围。**局部变量执行完后不会立刻销毁。
      <script>
          //fn外面的作用域可以访问fn内部局部变量
          function fn(){
            var num=10;
            function fun(){
               console.log(num);
           }
           return fun;
          }
          var f=fn();
          //f存的是fun
          f();
          //类似于
          var f=function(){
              console.log(num);
          }
    ==================================
          //fn外面的作用域可以访问fn内部局部变量
          function fn(){
            var num=10;
            return function(){
                console.log(num);
            }
          }
          //f存的是function
          var f=fn();
          f();
      </script>

闭包案列

  • 闭包模板:将模板里的函数从异步改为同步的(函数跟for循环同步,立刻执行。
  • function()最外层函数称作闭包函数。
  • 作用:增大变量范围。
              (function(i){
               //函数
              })(i);

点击某一个li输出对应li的索引号

在这里插入图片描述

  • for循环同步任务,马上执行。onlick异步任务,不会立刻执行。
  • 闭包是立即执行函数

普通方式

<body>
      <ul class="nav">
          <li>榴莲</li>
          <li>臭豆腐</li>
          <li>鲱鱼罐头</li>
          <li>大猪蹄子</li>
      </ul>
      <script>
          //动态添加属性
          var lis=document.querySelector('.nav').querySelectorAll('li');
          for(var i=0;i<lis.length;i++){
              //index为0 1 2 3
              lis[i].index=i;
              lis[i].onclick=function(){
                  console.log(this.index);
              }
          }
      </script>
</body>

闭包方式

  1. 第1个i传递给第5个i
  2. 第5个i传递给第2个i
  3. 点击第i个小li时。(lis[i].onclick)
  4. 打印出第4个i。
<body>
      <ul class="nav">
          <li>榴莲</li>
          <li>臭豆腐</li>
          <li>鲱鱼罐头</li>
          <li>大猪蹄子</li>
      </ul>
      <script>
          //动态添加属性
          var lis=document.querySelector('.nav').querySelectorAll('li');
          //闭包
          //第1个i传递给第5个i,第5个i传递给第2个i,点击第i个小li时。打印出第4个i。
          for(var i=0;i<lis.length;i++){
              //利用for循环创建4个立即执行函数
              //立即执行函数又叫小闭包,因为立即函数里面任何一个函数都可以使用它的i变量。
              //()();
              (function(i){
                  //console.log(i);
                  lis[i].onclick=function(){
                      //闭包,用了第一个function中二个i的值。
                      console.log(i);
                  }
              })(i);
          }
      </script>

立即执行函数又叫小闭包,因为立即函数里面任何一个函数都可以使用它的i变量。
闭包体现:用了第一个function中function(i)中i的值。

总结:for循环马上结束,而函数效果会一直保存。
当鼠标点击li时,调用lis[i].οnclick=function()。输出函数内的值。

三秒后,控制台打印li中所有元素

定时器里的回调函数都是异步任务。只是触发了才执行,即3秒后才执行。就算改成0也不会立刻执行,会把任务放到异步队列中。而for循环同步任务,马上执行。

      <script>
          //动态添加属性
          var lis=document.querySelector('.nav').querySelectorAll('li');
          for(var i=0;i<lis.length;i++){
              (function(i){
               setTimeout(function(){
                 console.log(lis[i].innerHTML);
               },3000)
              })(i);
          }
      </script>

输入公里数,输出打车价格
起步价13(3公里内) 每一公里加3 元
有拥堵,加10块度车费。

在这里插入图片描述

   <script>
       var car=(function(){
         var start=13;
         var total=0;
         return {
             price: function(n){
                  if(n<=3){
                      return start;
                  }
                  else{
                    total=start+(n-3)*5;
                    return total;                   
                  }
             },
             yd:function(flag){
               if(flag=true)
                  return total+10;
               else return total;
             }
         }
       })();
      console.log(car.price(5));//23
      console.log(car.yd(true));//33
      console.log(car.yd(false));//33
      console.log(car.price(1));//覆盖n=5 total=13
   </script>
  • 闭包:外面function访问里面function的total和start
  • 注意:局部变量会被新的值覆盖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值