JavaScript闭包

闭包是JavaScript中的一个重要概念,它允许内部函数访问并操作外部函数的变量,即使外部函数已经执行完毕。闭包在函数执行后不会自动释放,可能导致内存泄漏,但也有助于实现数据隐藏和模块化。文章通过示例解释了闭包的产生、作用、生命周期,并展示了如何在模块设计中利用闭包来封装私有数据和方法。
摘要由CSDN通过智能技术生成

闭包

闭包的产生

当一个内部函数调用外部函数的变量(函数)时,就产生了闭包。闭包是包含被引用数据的对象。因此闭包产生的条件有:

  1. 函数的嵌套
  2. 内部函数调用外部函数的数据

闭包的作用

  1. 使函数内部的变量在函数执行完后仍然存活,延长了局部变量的生命周期。
  2. 使得函数外可以读写和操作函数内部的变量。

闭包的生命周期以及缺点

闭包在嵌套内部函数定义执行完时就产生了,闭包在调用后不会自动释放,需要手动使其变为垃圾对象再被程序释放。(手动释放一般是将变量指向null)

由于闭包的特点,函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长,容易造成内存泄漏。

内存泄漏和内存

闭包产生,作用,生命周期实例

function fn1 () {
    //此时闭包就已经产生了
    var a = 1;
    function fn2 () {
      a++;
      console.log(a);
    }
    //返回fn2使得外部可以调用
    return fn2;
  }
//现在的fn即function fn2
var fn = fn1();

//通过调用fn操作a
fn();//2
fn();//3

//使得fn成为垃圾对象,闭包会被释放
fn = null;

闭包的实际应用

定义一个具有特定功能的JS文件(JS模块),将所有的数据和功能都封装在一个函数内部(私有的),只向外暴露一个包含n个方法的对象或函数。模块的使用者只需要通过模块暴露的对象,来调用相应的方法实现对应的功能。

//js模块:
function test() {
  //私有数据
  var msg = 'hello';
  var names = ['mike','john'];

  //操作私有数据的函数
  function doSomething() {
    console.log(msg)
  }
  function doOtherthing() {
    console.log(names.join())
  }

  //向外暴露包含多个方法的对象
  return {
    doSomething: doSomething,
    doOtherthing: doOtherthing
  }
}


//引用js模块的文件
//首先进行相关模块的引用
<script src="test.js"></script>
<script type="text/javascript">
//获得对象
  var module = test()
  //通过获得的对象中暴露的方法操作内部的数据
  test.doSomething()
  test.doOtherthing()
</script>

除了这种获得对象,调用方法的操作还可以将js模块中的函数设为自调用函数,然后在window上直接添加对象,这样在调用的时候就不用接收,可以直接通过window来调用。

练习

//example1
 var name = "window";
  var object = {
    name: "obj",
    getName: function () {
      return function () {
        return this.name;
      };
    }
  };
  
  console.log(object.getName()());  //window

 //example2
  var name2 = "window";
  var object2 = {
    name2: "obj",
    getName: function () {
    //产生了闭包
      var that = this;
      return function () {
        return that.name2;
      };
    }
  };
  
  console.log(object2.getName()()); //obj

example1:object.getName()返回的是function () {return this.name},
因此object.getName()()相当于在全局作用域下直接调用function () {return this.name},即window。

example2:object.getName()()相当于直接调用function () {return that.name2},由于产生了闭包,that指代object2这个对象,因此返回object2.name2,即obj。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值