美文网首页
图解 | 理解闭包

图解 | 理解闭包

作者: 鲸鲸景鲸叻 | 来源:发表于2020-03-29 16:10 被阅读0次

文 / 景朝霞

来源公号 / 朝霞的光影笔记

ID / zhaoxiajingjing

图 / 自己画

❥❥❥❥点个赞,让我知道你来过~❥❥❥❥


前情提要:

  1. 题目 | let和var的区别(一、二)
  2. 图解 | let和var的区别(一、二)
  3. 题目 | 带VAR和不带VAR的区别
  4. 图解 | 带VAR和不带VAR的区别
  5. 总结 | LET和VAR区别(三、四)
  6. 图解 | 作用域和作用域链
  7. 练习题 | 作用域和作用域链

0 / 看图说话

var n = 1;
function fn(){
    var n = 2;
    function f(){
        n--;
        console.log(n);
    }
    f();
    return f;
}
var x = fn();
x();
console.log(n);
公号ID:zhaoxiajingjing

△ 画简版的,不用的会出栈销毁

创建函数

  1. 开辟一个堆内存
  2. 把函数体中的代码以字符串格式存到堆内存中
  3. 把堆内存的地址赋值给函数名/变量名
  4. 函数在哪创建的,在执行时需要查找的上级作用域就是谁。即:FN[scope]:VO(G) F[scope]:AO(FN)

函数执行

  1. 开一个全新的栈内存:执行上下文EC(xx),会形成一个全新的私有作用域AO(xx)
  2. 形参赋值,变量提升(形参和在私有作用域中声明的变量:私有变量)
  3. 代码执行,把堆内存的代码字符串一行行拿出来运行
  4. 遇到变量:作用域链查找机制,找到它。
    • 看它是否为自己当前执行上下文/私有作用域下的私有变量
    • 是私有的,拿来用即可
    • 不是自己私有的,沿着scopeChain作用域链向上级作用域查找。
    • 上级作用域,如果有该变量,拿来用;如果没有该变量,再沿着作用域链向上级作用域查找
    • 一直找到全局作用域为止
  5. <u>私有变量和外界的变量没有必然关系,可以理解为被私有栈内存保护起来了,这种机制就是闭包保护机制</u>

其中,EC(FN) 执行上下文在执行完后,返回了一个小函数f,外面的x接收了小函数f的地址。那么,EC(FN)执行上下文/私有作用域中有东西被外界占用了,所以不会被销毁。

1 / 闭包

来~再念一遍:

<u>函数执行会形成一个全新的私有作用域,保护里面的变量不受外界干扰,这种保护机制就称为闭包。</u>

但是,我们经常听到这样说的:

函数执行会形成一个私有作用域,而这个栈内存不销毁,这样里面的私有变量与外面的不冲突,并且能保存这些值,叫做闭包。

这种说法呢,只把不销毁而留下来的称为闭包。

但,我理解的是当它形成了就已经是闭包了,这两种说法都OK,看个人理解认为哪种都OK。

闭包有两个作用:保护、保存

  • 保护:保护私有变量不让外界干扰,与外界没有必然联系
  • 保存:形成一个不销毁的私有作用域,私有栈内存里面的东西会保存下来;以后它里面的东西还能被调用到

2 / 练习题

请画图理解:作用域链查找机制、闭包机制。像上图画简单的即可。

  1. 输出结果是?fn函数执行完后是否会销毁?
console.log(a, b);
var a = 12,
    b = 12;
function fn(){
    console.log(a, b);
    var a = b = 13;
    console.log(a, b);
}
fn();
console.log(a, b);

注意:

var a = 12,
    b = 12;
// 等价于
var a = 12;
var b = 12;
var a = b = 1;
// 等价于
var a = 1;
b =1;
  1. 输出结果是什么?哪些执行完后不会销毁?为什么?
var i = 20;
function fn(){
    i -= 2;
    return function (n) {
        console.log(++i-n):
    };
}
var f = fn();
f(1);
f(2);
fn()(3);
fn()(4);
f(5);
console.log(i);
  1. 输出结果是?
var i = 0;
function A(){
    var i = 10;
    function x(){
        console.log(x);
    }
    return x;
}
var y = A();
y();
function B(){
    var i = 20;
    y();
}
B();

3 / 预告

如何判断THIS?

△ 文章首发,ID :zhaoxiajingjing

相关文章

  • 图解 | 理解闭包

    文 / 景朝霞来源公号 / 朝霞的光影笔记ID / zhaoxiajingjing图 / 自己画 ❥❥❥❥点个赞,...

  • js闭包问题

    javascript 闭包的概念,闭包的作用,闭包经典面试题详解(配图解) 函数作用域(闭包前置知识) 要彻底弄懂...

  • Gradle开发-Groovy闭包

    # 闭包 闭包的基础知识 闭包的使用 闭包 this,owner,delegate 的理解 总结 ## 闭包的基础...

  • 闭包详细图解

    前言 在我们了解了执行上下文EC之后,我们应该知道了,js执行的正常流程。但是我们在工作、面试时经常会遇到闭包这个...

  • Swift5 闭包及其应用

    关于如何理解闭包 学习闭包的第一个难点就是理解闭包,可能很多人用了很久的闭包都还不太清楚闭包到底是什么,我这里提供...

  • 【js基础修炼之路】— 深入浅出理解闭包

    之前对于闭包的理解只是很肤浅的,只是浮于表面,这次深究了一下闭包,下面是我对闭包的理解。 什么是闭包? 引用高程里...

  • 闭包理解

    这次我发现了个奇怪的问题,高程经典的闭包陷阱,竟然是把一个未执行的函数赋值给了一个数组项,当年的我太年轻,竟然没看...

  • 理解闭包

    什么是「闭包」。 「闭包」的作用是什么。在一个立即执行函数当中: 首先,假设以上几行代码运行在立即执行函数当中,那...

  • 理解闭包

    什么是闭包?闭包是什么时候创建的?能不能看到闭包?从这三点出发学习。 在维基百科中的闭包:词法闭包的简称。是引用了...

  • 理解闭包

    spark 比较难得一个事情之一就是当在集群上执行代码的时候,变量和方法的范围和生命周期。Rdds 的操作 能够修...

网友评论

      本文标题:图解 | 理解闭包

      本文链接:https://www.haomeiwen.com/subject/sqruuhtx.html