图解 | 理解闭包

文 / 景朝霞

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

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. 私有变量和外界的变量没有必然关系,可以理解为被私有栈内存保护起来了,这种机制就是闭包保护机制

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

1 / 闭包

来~再念一遍:

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

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

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

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

但,我理解的是当它形成了就已经是闭包了,这两种说法都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

你可能感兴趣的:(图解 | 理解闭包)