【前端面试基础题】作用域和闭包

170 阅读2分钟

前言: 闭包是前端面试时常考的一个题目,用于考查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