什么是闭包?
定义:闭包是指在 JavaScript 中,内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
闭包就是能够读取其他函数内部变量的函数,说白了闭包就是个函数,只不过是处于其他函数内部而已。
由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
用途是什么?
- 1.访问函数内部的变量
- 2.防止函数内部的变量执行完城后,被销毁,使其一直保存在内存中。
function outer(x) {
// 参数相当于局部的变量
function inner(y) {
console.log(x + y);
}
return inner;
}
var closure = outer(3);
closure(7); // 输出10
inner函数把自己内部的语句,和自己在声明时所处的作用域一起封装成了一个密闭的环境,我们就称之为闭包。
函数本身就是一个闭包,函数在定义的时候,就能记住自己的外部环境和内部语句,每次执行的时候,会参考定义时的密闭环境。
闭包的缺点
- 缺点:如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。
实际的项目应用
- 常用于项目的防抖节流函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function() {
//获取两个按钮
const debounceBtn = document.querySelector("#debounce")
const thorttleBtn = document.querySelector("#thorttle")
//防抖
function Debounce(fn, delay) {
let timer = null
//定义内部函数
const debounce = function() {
//形成闭包,timer变量不被释放,如果timer不为空则清除延时执行
if(timer) clearTimeout(timer)
//最后一次触发执行
timer = setTimeout(() => {
fn()
}, delay)
}
return debounce
}
debounceBtn.onclick = Debounce(() => {console.log("Debounce")}, 1000)
//节流
function Thorttle(fn, delay) {
let timer = null
//定义内部函数
const thorttle = function() {
//如果有延时任务则不在重新触发
if(!timer) {
timer = setTimeout(() => {
fn()
//delay时间后把timer设置为null
timer = null
}, delay)
}
}
return thorttle
}
thorttleBtn.onclick = Thorttle(() => {console.log("Thorttle")}, 1000)
}
</script>
</head>
<body>
<button id="debounce">防抖</button>
<button id="thorttle">节流</button>
</body>
</html>