前言: 闭包是前端面试时常考的一个题目,用于考查js基础,那回答这种题目的技巧是什么? 看完这个,相信你和我一样,能更深入的理解和掌握这个知识点。
首先在学习闭包前,我们需要先了解什么是作用域和自由变量的概念?
为什么呢?
因为,闭包是作用域应用的特殊情况。同时,还需要结合自由变量来一起理解。
一,啥是作用域
1,含义:某个变量合法的使用范围
2,分类:
全局作用域:全局可调用,例如:Window对象,Document对象
函数作用域:只能在当前函数使用
块级作用域(ES6新增):if,for,while 后接的{ } ==> 块 ( 用let const 写的,都适用)
另:
自由变量:1,一个变量在当前作用域没有定义,但被使用了;
2,向上级作用域,一层一层依次寻找,直到找到为止;
3,如果到全局作用域都没有找到,则报错
XX is not defined!
知道什么是作用域和自由变量后,我们开始看看什么是闭包?
二,啥是闭包
1,含义:有权访问另一个函数作用域中的变量的函数
函数+创建该函数的环境(环境:由闭包创建时,在作用域中的任何局部变量组成)
2,两种表现:(闭包是作用域应用的特殊情况)
(1)函数作为返回值:
//声明函数
function create(){
const a = 100
return function(){
console.log(a)
}
}
//调用函数
const fn = create()
const a = 200
fn() //打印结果:100
fn = null //手动释放内存
(2)函数作为参数被传递
//声明函数
function print(fn){
const a = 200
fn()
}
const a = 100
function fn(){
console.log(a)
}
//问题:打印结果为?
fn() //打印结果:100
print(fn)
总结:
一,闭包:就在一个函数内部创建另一个函数,将函数的内部与外部连接起来
优点:
a,保证函数不受外界干扰,实现封装,避免命名冲突。
b,可以在内存中保存函数变量,充当缓存。
缺点:
a,内存消耗很大,容易造成内存泄露(所以,需要手动释放内存)
二,解题关键:
所有自由变量的查找,是在函数定义的地方向上级作用域查找,而不是在执行的地方。
加更:实际开发中闭包的应用
(隐藏数据,如做一个简单的cache工具)
//定义函数
function createCache(){
const data={...}//闭包中数据,被隐藏,不被外界访问
retur({
set:function(key,val){
data[key] = val
},
get:function(key){
return data[key]
}
})
}
//调用
const c = createCache()
c.set('a',100)
console.log(c.get('a')) // 100