JS闭包的理解及常见应用场景

闭包的概念

闭包是指有权访问另一个函数作用域中的变量的函数,本质也就是在函数里面返回一个函数
一般就是一个函数A,return其内部的函数B,被return出去的B函数能够在外部访问A函数内部的变量,这时候就形成了一个B函数的变量背包,
A函数执行结束后这个变量背包也不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问。

闭包形成的原理

延长作用域链,当前作用域可以访问上级作用域中的变量

闭包解决的问题

能够让函数作用域中的变量在函数执行结束之后不被销毁,同时也能在函数外部可以访问函数内部的局部变量。

闭包带来的问题

由于垃圾回收器不会将闭包中变量销毁,于是就造成了内存泄露,内存泄露积累多了就容易导致内存溢出。

所以使用完闭包后,可以通过对闭包 geta = null(下面代码) ,让垃圾回收器回收

实现一个简单的闭包

function fun(){
  var a = 10;//fun函数作用域内部的变量
  return ()=>{
    return a;//在此可以访问到fun函数作用域的a
  }
}

var geta = fun();
var a = geta();
console.log(a);//通过闭包我们就可以在fun函数外部访问到fun函数内部作用域的变量

闭包的作用

  • 延迟变量的生命周期
  • 创建出私有作用域 (如 vue中data返回一个对象)
  • 闭包可以在函数外部访问到函数内部作用域的变量
  • 闭包可以让访问变量不会被垃圾机制回收

因为受js链式作用域的影响,

  • 子对象会一级一级向上寻找所有父对象的变量,反之不行。
  • js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量

闭包的应用场景

  • 使用场景一:给对象设置私有变量并且利用特权方法去访问私有属性
function Fun(){
  var name = 'tom';
  
  this.getName = function (){
    return name;
  }
}

var fun = new Fun(); 
console.log(fun.name);//输出undefined,在外部无法直接访问name
console.log(fun.getName());//可以通过特定方法去访问
  • 使用场景二:采用函数引用方式的setTimeout调用
    setTimeout:接收两个参数,第一个参数可以是一段js代码,亦可以是一个函数,第二个参数是我们延迟执行第一个参数的时间(实际上不是延迟执行,而是延迟加入执行队列),在此我们要讨论的情况是第一个参数是一个函数的情况,我们传入的参数实际上是函数对象的引用,那这时候就不能向函数传参了,那么闭包就派上用场了
function fun(num){
  var age = num;
  return function(){
       console.log(age);
  }
}

var getAge = fun(200);//传入需要的参数,得到函数(闭包)的引用
var age = setTimeout(getAge,1000);//正确输出
  • 防抖节流函数
  • 单例模式
  • 实现柯里化
  • Vue中数据响应式Observer中使用闭包等。

你可能感兴趣的:(js,javascript)