闭包的简单初步理解

闭包的简单初步理解

闭包的初步理解

·

1 min read

首先说明我是一个学生,属于自学前端开发者,今天想要和大家聊的话题是关于闭包,大家可能接触闭包的时候是通过视频学习,然后去看专栏或者博客,我最近在候策的《前端开发核心知识进阶》中发现了很多有意思的知识点,能够帮助大家进一步提升对于闭包的理解

2.你真的了解闭包吗?

对于闭包的理解,可能很多同学的理解有很多不同的见解, 在这里插入图片描述 这是MDN关于闭包的理解,大家刚开始接触的时候可能对于文中提到了一些概念并没有抓住,比如周围状态(词法环境)这里提到的环境究竟是什么,大家可能会想到肯定是作用域,作用域链那些呀,想要产生闭包,肯定需要多层作用域, 以下代码简单叙述了闭包

const fn = function () {
    let number = 0
    return function () {
        number++;
        console.log(number)
    }
}
let foo = fn();
foo(); //1
foo() //2
...

这道题很简单,我们都知道当我们调用一个函数的时候,函数就会销毁,包含内部的数据,但是从这道题可以看出由于我们返回了一个函数,函数中的number还在被使用,于是父级作用域(fn)函数的上下文并不会被销毁,而是被保存在全局中,所以当我们调用foo函数的时候(这个时候foo函数可是全局的哦)我们可以访问fn函数内部的数据 于是候策老师给出的结论相信大家更容易理解: 函数嵌套函数的时候,内层函数引用了外部函数作用域下的变量,并且内部函数在全局环境下可以访问外部函数,进而形成闭包

看到这里你是否对于闭包清晰了许多?但是我接下来说的内容能够让大家充分理解闭包,更能让大家认识到JavaScript灵活以及强大 如一下例题

var fn = null;
const foo = ()=> {
    var a = 2;
    function innerFoo() {
        console.log(a)
    }
    fn = innerFoo
}
const bar =()=> {
    fn()
}
foo()
bar() //2

这道题大家可能迎刃而解,觉得小菜一碟,那么我先不叙述 ,来看加强版,你可能就会有疑惑

var fn = null;
const foo = ()=> {
    var a = 2;
    function innerFoo() {
        console.log(c)
        console.log(a)
    }
    fn = innerFoo
}
const bar =()=> {
    var c = 100;
    fn()
}
foo()
bar()

这里大家可能会觉得肯定输出100,2,因为当执行bar的时候执行fn函数也就是innerFoo函数中的log(c)找不到,所以去外层作用域查找,正好找到了bar的父级作用域内的c呀,如果你是这样想的,那么就错了 正确答案是报错:c is not defined 原因非常简单 : bar函数中的变量c 可不是fn函数的父级作用域,大家可要看清楚,大家可以看看第一道例题,我们写的是return 一个函数,进而有了父级作用域和子级作用域,所以这里压根就没有形成作用域的层级关系,所以谈不上由作用域链向上查找了,

这里我要和大家还要说的一个重点就是关于执行上下文的要点,也是帮助大家识别各种不同的作用域,以及识别作用域绑定的位置,以及改变, 看这道题,我们把innerFoo函数复制传给了fn,那么这个fn的作用域的父级作用域是不是foo的作用域,这里形成了2层不同的作用域,可以通过作用域链查找,但是当我们在bar函数中调用fn的时候,大家需要警惕,由于fn函数的父级作用域已经确定,那么就不可更改,所以与bar的作用域压根没有任何关系,如果我们想要验证这个fn的作用域在bar函数下还是foo函数的子级作用域呢? 非常简单,直接在foo函数中定义一个变量c(var c = 101),你会发现可以正常访问 那么也就验证了我刚才说的话, 这道题也清楚了告诉我们函数的作用域一旦确定,那么不会轻易更改,这当然也属于闭包的知识,能够帮助大家充分理解闭包

3.总结

闭包的定义看上去确实很简单,但是它和内存,执行上下文,以及作用域,作用域链紧密相连,如果你对其中一个知识点存在疑惑,那么你可能无法正确理解闭包,也许面试的时候你可能就错了,所以请大家好好梳理下这几个知识 看到这里我相信你也是一个前端开发热爱者,如果真的热爱,我们就应该抱着学习的心态去不断加深对于这门语言乃至这个行业的深度,这样我们才能离高薪越来越近, 如果大家想共同交流可以来我的qq交流群一起交流学习:552572712