学习笔记:JavaScript的闭包

373 阅读1分钟

了解闭包的前提,需要先知道JavaScript的变量作用域

  1. 全局变量

  2. 局部变量

    const a = 1 function func(){ console.log(a); } func() // 1 函数内部可以读取全局变量

    function f1(){ const a=1; } console.log(a) // Uncaught ReferenceError: a is not defined 函数外部无法读取函数内的局部变量

此外ES6的const和let本身就有块级作用域的概念。

有时候,我们就需要得到函数内的局部变量,那怎么办?闭包的出现,就是为了解决这个问题。

function f1(){
  
    const n=1;
    
    function f2(){
        console.log(n);
    }

    return f2;
}

const result=f1();

result(); // 1

所以闭包的概念,我个人是这样理解:闭包是一个函数,这个函数定义在某个函数的内部。

理解有不对的地方请指正~

f2 函数就是一个闭包,这个函数定义在f1的内部。

闭包除了让外部函数可以读取函数内部的变量外,另一个用户就是让这些变量的值始终保持在内存中。

function f1() {

    let n = 1;

    function f2() {
        n = n + 1;
        console.log(n);
    }

    return f2;

}

const result = f1();

result();  // 2
result();  // 3
result();  // 4
result = null // 释放对闭包的引用 

函数f1中的变量n一直保存在内存中,并没有在f1调用后被自动清除。因为f1是f2的父函数,而f2被赋给了全局变量result,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。

闭包常见的应用场景是创建私有变量和方法

function Person() {

    // 私有变量
    const age = 11;

    function run() {
        console.log(2);
    }

    // 访问方法
    this.getAge = function () {
        return age;
    };
}

const age = new Person();
console.log(age.getAge());  // 11