javascript闭包

前言


  我们知道,变量根据作用域的不同分为两种:全局变量和局部变量。

  • 函数内部可以访问全局变量和局部变量
  • 函数外部能访问全局变量,不能访问局部变量
  • 当函数执行完毕,本作用域的局部变量销毁。  

  如:

function foo() {
  let a = 1;
}
foo();
console.log(a);  
//打印报错:Uncaught ReferenceError: a is not defined

  上面代码中,由于变量a是函数内的局部变量,所以外部无法访问。

  但是,在有些场景下,我们就是想要在函数外部访问函数内的局部变量的时候,就需要引入闭包的概念。

 

闭包的概念和代码举例


   闭包的概念:闭包指有权访问另一个函数作用域中变量的函数。

  简单理解就是,如果这个作用域可以访问另外一个函数内部的局部变量,那就产生了闭包 (此时,我们可以把闭包理解为一种现象),而另外那个作用域所在的函数称为闭包函数。

  闭包代码举例

function fn1() {
  let a = 10;
  
  function fn2() {
    console.log(a);
  }
  fn2();
}
fn1();

  打印结果:10

  上面代码中,函数fn2的作用域访问了fn1中的局部变量,那么此时在fn1中就产生了闭包,fn1称为闭包函数。

 

闭包的创建


   闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互补干扰。闭包会发生内存泄漏,每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删除,保留一根指针给内部活动对象。

  闭包内存泄漏为:

   一块被分配的内存既不能使用,也不能回收。作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这最终会消耗尽系统所有的内存,从而影响性能,甚至导致程序崩溃。

  内存泄漏的解决办法:

   常用的解决方法就是在JavaScript代码段运行完的时候将形成循环引用的JavaScript对象手动设置为空,切断引用。

function fn1() {
  let a = 10;
  
  return function() {
    console.log(a);
  }
  a = null; //添加的语句 } fn1();

 

闭包的作用


 

function Person(){ 

  var name = "default";

  return {
    getName : function(){
      return name;
    },
    setName : function(newName){
      name = newName;
    }
  }
};

var john = Person();
print(john.getName());  //default
john.setName("john");
print(john.getName());  //john

  总结:

  1️⃣ 闭包可以从外部读取函数内部的变量,也就是延伸了变量的作用范围,避免了使用全局变量,防止全局变量污染;

  2️⃣ 将创建的变量的值始终保持在内存中;(代码中,name一直保存在内存中,并没有在对象中的两个函数调用后被清除)

  3️⃣ 闭包可以使不同的对象拥有独立的成员及状态,互不干涉;(setName和getName都是Person这个类的实例,两个实例对name这个成员的访问是独立的互不影响的)

 

posted @ 2020-10-11 18:27  你吃辣条儿吗  阅读(124)  评论(1编辑  收藏  举报