进修笔记:JavaScript 闭包是怎样经由过程作用域链霸占更多内存的?

JavaScript 闭包是怎样经由历程作用域链霸占更多内存的?

本文是作者进修《JavaScript 高等程序设计》7.2第一小节的一点个人明白,细致教程请参考原课本。

在弄清楚这个题目之前,我们有必要搞清楚下面这几个题目:

起首,什么是闭包?

定义:闭包 是指 有权接见另一个函数作用域中变量的函数。

怎样建立闭包?

在一个函数内部建立另一个函数,是建立闭包最常见的体式格局。

一个平常的函数实行的时刻都发生了什么?

  • 建立一个实行环境,内里有这个函数的变量对象,保留了函数可接见的一切数据。

  • 建立了作用域链,用来保证可接见变量的有序接见。

  • 函数实行历程建立了一个函数的运动对象,作用域链的最前端指向这个对象。

  • 函数读取写入值,在作用域链内里查找。

  • 函数实行终了返回值后:实行环境、作用域链和运动对象一并烧毁。

明白了这些以后,考核下原书的代码:

function createCompare(property){
    return function(obj1,obj2){
        var value1=obj1.property;
        var value2=obj2.property;
        
        if (value2 < value1){
            return 1;
        } else if (value2 >value1){
            return 1;
        } else {
            return 0;
        }
    };
}

var compareNames = createCompare("name");
var result = compareNames({name : "mars1"},{name : "mars2"});

个中,createCompare 函数返回了一个匿名函数,这个匿名函数就是一个闭包。它援用了createCompare函数的参数变量property。

建立compareNames 变量的时刻,就建立了createCompare函数的运动变量:个中property = name etc. 同时返回了匿名函数给compareNames变量,它也有本身的实行环境与作用域链,作用域链援用了建立的compareNames运动对象。

result 定义历程,建立了compareNames的运动对象,个中obj1 = {name : “mars1”} etc.

如许,为result 赋值的compareNames函数实行环境的作用域链以下:

compareNames运动对象 → createCompare运动对象 → 全局对象。

那末题目来了,这个闭包是怎样致使占用更多内存的?

函数实行终了,compareNames 变量并未消逝,不会被渣滓接纳,而它指向的闭包(匿名函数)的作用域链援用着createCompare 函数的运动变量。所以createCompare函数虽然实行终了返回了匿名函数,然则它的运动对象并不会和实行环境、作用域链一样被烧毁,由于另有compareNames的作用域链在援用。如许就相当于闭包照顾了包括它的函数运动对象。

因而要开释compareNames照顾的作用域,必需手动消除援用:

var compareNames = null;
    原文作者:Mars
    原文地址: https://segmentfault.com/a/1190000008398011
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞