闭包

123 阅读3分钟

感谢b站up主尚硅谷前端面试视频

感谢b站up主技术蛋老师的JS面试题详解系列视频

感谢b站up主峰华前端工程师的 JavaScript 基础语法教程 | 2020年最新版!系列视频

感谢简书作者这波能发杀的前端基础进阶

感谢饥人谷课程

闭包

闭包是JS的一种语法特性,一个语言可以选择是否支持闭包这个语法特性。

什么是闭包

  1. 闭包就是密闭的容器,用于存储数据。(存储数据的容器:变量、对象、数组、es6引入的set、map容器,分这么多类别是基于存储数据的结构不同)
  2. 闭包是一个特殊对象,存放数据的格式为 key:value

闭包形成的条件

  • 函数嵌套
  • 内部函数引用外部函数的局部变量
function f1(){
  const a = 1;
  return function(){
    console.log(a);  // 内部函数引用外部 f1 函数的局部变量 a
  }
}
f1()  // 外部函数调用

闭包的组成

由执行上下文(A)和在该执行上下文中创建的函数(B)两部分组成。

当B执行时,如果访问了A中变量对象中的值,那么闭包就会产生。

闭包的应用场景

function fun(){
  const a = 1;
  return function(){
    console.log(a);  // 内部 fun2 函数引用外部 fun 函数的局部变量 a
  }
}
let fun2 = fun()  // 外部函数调用
fun2()

这个内部函数可以访问外部函数作用域的变量,并且如果外部函数不暴露这个内部函数的话,那么外界就不知道这个内部函数的存在,只能在自己的内部使用,也就形成了一个私有的函数。

// 计算两个数的平方和
function squSum(a, b){
    function squ(x){    // 内部函数单独负责计算一个数的平方
        return x * x;
    }
    return squ(a) + squ(b);
}
console.log(squSum(2, 3));  // 13
  • 内部函数也可以作为返回值返回出去,整个的外部函数就形成了一个高阶函数,即返回函数的一个函数。
function person(){
    let name = "马云";
    function getName(){
        return name;
    }
    return getName;
}

var getName = person();
console.log(getName());  // 马云
  • 上例的做法,等于给name设置了只读属性,外界只能访问他的值,而不能修改他的值,起到了保护作用,person()即为高阶函数。

闭包的优点

延长外部函数局部变量的生命周期。通过闭包,我们可以在其他的执行上下文中,访问到函数的内部变量。

函数的执行上下文,在执行完毕之后,生命周期结束,那么该函数的执行上下文就会失去引用。其占用的内存空间很快就会被垃圾回收器释放。可是闭包的存在,会阻止这一过程。

闭包的缺点

使用不当容易造成内存泄露

闭包的应用场景

柯里化

模块化