js闭包的简单理解

86 阅读2分钟

一、闭包是什么?

浅显回答就是方法里面返回一个方法,这是闭包的一个表现形式

// 这就是一个闭包
function a() {
    let a1 = 1;
    return function() {
        return a1;
    }
}

二、闭包存在的意义是什么

1、延长变量的声明周期

    let a = 'xiaoming'

    function func1() {
        let b = 1
        console.log(a); // 在方法里面是可以访问到方法外部的值的   xiaoming
    }
    // console.log('b :>> ', b); // 但是在外面拿不到里面的值   Uncaught ReferenceError: b is not defined
    func1();

    // js执行机制, js运行时会生成一个临时的变量对象AO
    // AO(Active Object)
    // AO里就会存储所有的方法以及局部变量都会存在AO里面, 全局变量是不会在AO里的, 当这个方法执行完的时候, b就用完了, 就回收了, 所以外部访问不到

    // 作用域链 函数包着函数就形成了作用域链, 所谓作用域链的查找就是一级一级往上查找, 就近原则,
    let name = "张三"

    function func2() {
        let name = "李四"

        function func3() {
            let name = "王五"
            console.log('name :>> ', name);
        }
        func3();
    }
    func2();

2、创建私有环境

    // 闭包(Closure)----沟通内外部方法桥梁
    function outer() {
        let a1 = 111;
        let a2 = 222;
        return function inner() {
            return a1;
        }
    }

    function func5() {
        let getInnerData = outer();
        console.log('getInnerData :>> ', getInnerData);
        console.dir(getInnerData);
    }
    func5(); // getInnerData :>>  ƒ inner() {return a1;}
    
    // 闭包会常驻内存 => 慎用

三、Vue中的一道面试题----data({return {}})为什么是一个函数(闭包设计)

Vue是一个单页应用,会有很多个组件,每一个组件都有一个data,通过闭包给每一个组件都建了一个私有域空间,
这样就保证了各个组件之间都拥有一个私有的作用域,互不影响;
如果不用闭包,用一个常规对象obj = {} ,这样就会导致各个组件的数据会相互干扰

四、举个例子理解闭包

    // 以私有作用域举个例子
    // 创建一个计数器
    // 经典闭包,num、changeBy()就是makeCounter的私有作用域
    // 外部是没法拿到num和changeBy()的
    let makeCounter = function() {
        let num = 0;

        function changeBy(value) {
            num += value;
        }
        // 给你什么,你才能拿到
        return {
            add: function() {
                changeBy(1);
            },
            reduce: function() {
                changeBy(-1);
            },
            value: function() {
                return num;
            }
        }
    }
    let counter1 = makeCounter();
    let counter2 = makeCounter();

    counter1.add();
    counter1.add(); // 2
    // 当改变counter1的时候,counter2是不受影响的
    counter2.add();
    console.log('counter2.value() :>> ', counter2.value()); // 1
    console.log('counter1.value() :>> ', counter1.value()); // 2

    // 用闭包可以诠释面向对象编程的好处----数据的隐藏和封装

最后

在学习过程中,代码写的比较乱,我自己看也许会感觉比较清晰,但是读者看着就会稍有迷糊,建议结合自身的学习资料和笔记对照着来看。

本人才疏学浅,文笔拙劣,如有不足之处,还请大家指正。