还搞不懂闭包吗?一文深入了解闭包应用场景及其原理什么是闭包? 先说理论: 闭包就是可以在一个作用域里访问另外一个作用域。
什么是闭包?
先说理论:
闭包就是可以在一个作用域里访问另外一个作用域。
就比如函数内部作用域访问全局作用域,全局作用域访问函数内部作用域。
具体的体现:
function closureFactory(){
let age=0;
return function(){
age++;
console.log(age);
}
}
const getData=closureFactory();
getData(); //1
上面的这个就是一个最简单的闭包。
可能有的人到这里还会不清楚哪一部分是闭包,是整个closureFactory吗,还是返回的匿名函数?
闭包具体指的是返回的这个匿名函数。
上面说到两个闭包的例子,这里就是全局作用域访问函数内部作用域。
另外一个是函数作用域访问全局作用域,这里其实就是我们平时写的函数。它其实就是一个闭包,在函数内部作用域找不到变量的时候,函数会从外部作用域寻找,直到找到目标变量。
闭包原理
先了解一个概念:词法作用域
在一个代码块的声明中,会出现一个词法作用域。这个词法作用域记录了内部词法环境和外部词法环境。
一个变量声明在全局作用域中,此时全局作用域的内部词法环境就记录了该变量,全局作用域的外部词法环境为null。
此时在全局作用域中声明一个函数,全局作用域就记录了该函数的声明。函数的声明产生了一个函数作用域,该作用域的内部词法环境就记录了函数内部的变量,外部词法环境就记录了全局作用域的内部词法环境。
前提知识储备完成,来解释一下闭包
当函数内部找不到变量就会通过外部词法作用域去寻找,一直找到全局作用域的词法环境。
这就是平时调用函数出现的情况。
那么闭包为什么可以实现全局作用域访问内部作用域?
我们知道的是,闭包是函数(后续称为闭包工厂)内部返回的一个新的函数。那么此时闭包工厂的内部词法环境就记录一个变量和一个闭包。
那么此时闭包的词法环境是怎么样的?
此时闭包的词法环境有两个部分:内部词法环境以及对应的外部词法环境(闭包工厂的内部词法环境)。
当我们调用闭包,并且访问闭包内部词法环境中没有的变量,此时闭包会通过外部词法环境去寻找,首先找的就是闭包工厂的词法环境,直到全局的词法环境。
闭包的作用
1.实现私有变量
function closureFactory(){
let age=0;
return function(){
age++;
console.log(age);
}
}
const getData=closureFactory();
getData(); //1
这就是一个私有变量,函数外部无法调用或者改变,只能通过闭包。
2.实现缓存
function closureFactory(){
let data=new Map();
return async function(input){
if(data.has(input)){
return data.get(input);
}
else{
// 模拟的发送请求的代码
const res=await request(input)
// 将请求获取到的数据存储在缓存中
data.set(input,res)
return res;
}
}
}
const getData=closureFactory();
async function use(tar){
const result=await getData(tar)
console.log(result);
}
use('11111');
use('22222');
use('11111');
这里就可以做到一个简单的存储网络请求的响应。
3.实现动态改变函数功能
function multipiler(num){
let number=num;
return function(mult){
let res=number*mult;
console.log(res);
}
}
let double=multipiler(2);
let thirs=multipiler(3);
double(14);
double(35);
thirs(3)
上面这段代码就实现了通过参数动态的改变了函数功能的些许变化。
4.实现节流和防抖
这里就不写代码示例了,哈哈。
网上有很多手写节流防抖和代码。大家可以去看看是不是我说的闭包,相互印证一下。
作者知识有限,有错误的地方,欢迎指正啊!
转载自:https://juejin.cn/post/7418061055207800841