感谢b站up主尚硅谷前端面试视频
感谢b站up主技术蛋老师的JS面试题详解系列视频
感谢b站up主峰华前端工程师的 JavaScript 基础语法教程 | 2020年最新版!系列视频
感谢简书作者这波能发杀的前端基础进阶
感谢饥人谷课程
闭包
闭包是JS的一种语法特性,一个语言可以选择是否支持闭包这个语法特性。
什么是闭包
- 闭包就是密闭的容器,用于存储数据。(存储数据的容器:变量、对象、数组、es6引入的set、map容器,分这么多类别是基于存储数据的结构不同)
- 闭包是一个特殊对象,存放数据的格式为
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()
即为高阶函数。
闭包的优点
延长外部函数局部变量的生命周期。通过闭包,我们可以在其他的执行上下文中,访问到函数的内部变量。
函数的执行上下文,在执行完毕之后,生命周期结束,那么该函数的执行上下文就会失去引用。其占用的内存空间很快就会被垃圾回收器释放。可是闭包的存在,会阻止这一过程。
闭包的缺点
使用不当容易造成内存泄露