作为一名前端搬砖人,提起闭包我就心梗。
我听得最多的一句话就是,“闭包,只可意会不可言传”。
简单来说,闭包就是指有权访问另一个函数作用域中的变量的函数。最常见的形态就是在一个函数的内部创建另一个函数。
结构
-
外部函数的返回结果是一个函数,暂且称为内部函数。
-
内部函数中使用了外部函数中的变量(成员)。
现象
-
外部函数执行结束后,被内部函数使用的变量(成员)不会被销毁释放。
-
生命周期:在整个代码执行结束时才销毁。
-
作用域:只能在函数内部访问。
目的
1)每次去执行返回的内部函数,都可以使用该变量(成员)。并且该变量(成员)的值可以变化,也就是说,该变量(成员)可以在函数多次执行过程中保存状态。在其它一些语言中称为静态变量。例:记录函数调用次数。
2)该变量可以被返回的内部函数访问。但是外部其它代码无法访问,防止意外修改,起到了保护作用。
Demo
例1:
// 闭包
function makeFn() {
let msg = '函数作为返回值'
return function() {
console.log(msg) // 内部函数访问外部函数的 msg
}
}
// 外部函数 makeFn 执行完, 应清理所有, 但其 msg 被 fn 使用, 所以 msg 不会销毁
const fn = makeFn()
fn() // 第一,msg 可以在 fn 中反复使用
console.log(msg) // 第二,msg 在外部这里是访问不到的,它被保护了起来
例2:
// 闭包
function once (fn) {
let done = false
return function () {
if (!done) { // 使用(引用)了外部函数的变量
done = true
fn.apply(this, arguments)
}
}
}
let pay = once(function (money) {
console.log(`支付: ${money} RMB`)
})
pay(5)
pay(5)
例3:
/*
求数字的平方
pow(5, 2)
pow(4, 2)
可以把 2 固定下来
*/
function makePower(power) {
return function (number) {
return Math.pow(number, power)
}
}
// 返回 求平方 的函数
let power2 = makePower(2)
console.log( power2(4) ) // 4的平方等于16
console.log( power2(5) ) // 5的平方等于25
// 返回 求立方 的函数
let power3 = makePower(3)
console.log(power3(4)) // 4的立方等于64
console.log(power3(5)) // 5的立方等于125
/*
我的理解:
power 作为参数,理解为外部函数的局部变量
内部函数中引用了它,内部函数被返回
所以,这是闭包的结构
函数参数的灵活性不同, 有的经常变, 有的偶尔变
可以把多参数的函数, 细粒度一些, 如上面代码
*/
/*
Call Stack 调用栈
Scope 作用域
Local 局部作用域
Global 全局作用域
通过var定义的变量会在全局
Script 通过let定义的变量可以在这个位置看到
Closure (makePower) 说明这个闭包引用了 makePower 外部函数中的变量(成员)
内部函数执行时, 才可以看到闭包相关内容, 即看到它所引用外部函数中的内容
*/
例4:
/*
不同级别员工的工资
生成计算工资的函数. 不同级别员工 基本工资不同
基本工资 base 12000, 15000
绩效工资 performance
*/
function makeSalary (base) {
return function (performance) {
return base + performance
}
}
// 基本工资为 12000 的 工资计算函数
let salaryLevel1 = makeSalary(12000)
// 基本工资为 15000 的 工资计算函数
let salaryLevel2 = makeSalary(1500
console.log(salaryLevel1(2000)) // 总工资 14000
console.log(salaryLevel2(3000)) // 总工资 18000
不管你的理解如何,只要你能写出闭包的案例,你就已经一脚踏入了前端的世界。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!