有段代码如下:

function createCounter(){
    let i=0;
    function increment(){
        i++;
    }  
 
    function getValue(){
        return i; 
    }
    return {increment,getValue}
}

const counter = createCounter();

在这段代码中,运用了函数的3个特点:

  • 在函数内部生成了一个局部的变量 i;

  • 嵌入了 increment 和 getValue 这两个函数方法;

  • 把函数作为返回值用 return 来返回

当执行完createCounter函数后,按道理相关变量 i 应该被销毁了,并完成相关的垃圾回收。但是我们仍然可以访问它内部的变量 i,并可以继续调用 increment 和 getValue 方法。当我们尝试增加 i 的值的时候,会看到返回不断增加的结果。

counter.increment(); 
counter.getValue(); // 返回1
counter.increment();
counter.getValue(); // 返回2

 

原理解析如下,当 JavaScript 引擎解析函数的时候,用的是延迟解析,而不是及时解析。这样做的目的是减少解析时间和减少内存使用。所以在语法解析的时候,只会解析到 createCounter 函数这一层,而不会继续解析嵌入的 increment 和 getValue 函数。

但是引擎同时又有一个预解析的功能,可以看到 increment 和 getValue 会引用一个外部的变量 i,所以会把这个变量从栈移到堆中,就用了更长的记忆来记录 i 的值

有一点要注意的是,考虑到性能、内存和执行速度,当使用闭包的时候,我们就要注意尽量使用本地而不要用全局变量

posted on 2024-05-25 15:51  龙种人  阅读(4)  评论(0编辑  收藏  举报