详细介绍 javascript 闭包相关概念

本文介绍了JavaScript中的高阶函数,包括将函数作为参数传递和作为返回值输出。接着,详细解释了闭包的概念,即一个函数能够访问另一个函数内部的局部变量,并通过示例展示了闭包如何用于扩展变量作用域。文章还讨论了闭包在处理循环中的作用,如在按钮点击事件中的应用,以及如何避免内存消耗过大的问题。最后,给出了闭包的常见实现方式和使用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在介绍闭包之前我们先了解一下高阶函数吧,听起来很高大上对名字,其实我们可能经常在用,只是不知道它叫这个名字。
高阶函数是对其他函数进行操作对函数,它分为两种情况
  1. 将函数作为参数传递
      function fn(a,b,callback) {
        console.log(a+b);
        callback && callback();
      }
      fn(1,2,function () {
        alert("aa");
      });
  1. 将函数作为返回值输出
      function fn() {
        return function () {
          alert("bb");
        };
      }
      fn()();
看起来是不是很熟悉,第二种方式是不是让我们想起了闭包呢,只是这个例子没有变量对引用,所以不能称之为闭包,下面我们来说一下闭包。
什么是闭包?
  • 闭包是一个函数(一个函数可以访问另一个函数内部局部变量)在 javascript 中只有函数内部的子函数才可以访问该函数的局部变量,所以我们闭包的写法一般是在函数内部返回一个子函数,这个子函数使用了函数内部的变量,然后在外部调用这个子函数,这样就会使得一个函数可以访问到另一个函数内部的变量,就形成了闭包。
闭包的作用?
  • 延伸变量的作用范围
举例示范
  • 假设页面有四个按钮,点击这四个按钮的时候输出每个按钮的索引。
 // 额外附加一下for循环中let 和var 的区别
 
    var lis = document.querySelectorAll('li')
    
      for(var i=0;i<lis.length;i++){
        lis[i].onclick=function(){
          console.log(i)  //每次点击都输出4
        }
      } 

      for(let i=0;i<lis.length;i++){
        lis[i].onclick=function(){
          console.log(i)  //输出0,1,2,3
        }
      } 
在这个例子中我们只需要把 var 改为 let 就可以正常输出了,因为for是同步的,当我们点击的时候已经执行完了,而 i 的值也会因为 var 的原因覆盖为最后的结果4,当我们使用 let 的时候,由于块级作用域的影响,导致每次迭代过程中的 i 都是独立的存在,所以就可以正常输出。

那假如我们就要使用 var 呢,怎么才可以是它正常输出呢?
  1. 我们可以在每个li上增加一个属性来记录 i 的值
eg:
   for(var i=0;i<lis.length;i++){
        lis[i].index = i;
        lis[i].onclick=function(){
          console.log(this.index)
        }
    }
  1. 我们可以立即执行函数来传递 i 的值,这个时候就用到了闭包
eg:
   for (var i = 0; i < lis.length; i++) {
       (function (i) {
         lis[i].onclick = function () {
            console.log(i)
         };
       })(i);
     }
在这个例子中变量 i 通过立即执行函数传递进来的,它是立即执行函数的局部变量,但是在点击事件函数中使用了i, 并且点击的时候调用了这个点击事件函数,使得在立即执行函数外面的作用域可以访问到函数内部的变量,所以就形成的闭包。
下面我们来看看闭包的常用写法:
     function fn() {
        var num = 10;
        return function () {
          alert(num);
        };
      }
      fn()();
     function fn() {
        var num = 10;
        function fun () {
          alert(num);
        };
        return fun
      }
      fn()();
return 除了可以返回函数,还可以返回对象
     function fn() {
        var num = 10;
        return {
          fun: function () {
            alert(num);
          },
        };
      }
      fn().fun();
使用闭包的注意点
  • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值