账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    但如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当做垃圾回收。
    51
    0

    js 权威指南-第六版-中 p184 实现闭包,有段话理解不了;全文是这样:

    每次调用 js 函数时,都会为之创建一个新的变量对象用来保存局部变量,把这个对象添加至作用域链中。当函数返回时,就从作用域链中将这个绑定的变量对象删除。如果不存在嵌套的函数,也没有其他引用指向这个绑定对象,他就会被当做垃圾回收掉。如果定义了嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象。但如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当做垃圾回收。但是如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数,他就不会被当做垃圾回收,并且他所指向的变量绑定对象也不会被当做垃圾回收。

    我分成三段理解:

    1、每次调用 js 函数时,都会为之创建一个新的变量对象用来保存局部变量,把这个对象添加至作用域链中。当函数返回时,就从作用域链中将这个绑定的变量对象删除。如果不存在嵌套的函数,也没有其他引用指向这个绑定对象,他就会被当做垃圾回收掉。

    可以理解上面一段,下面两段不太清楚;

    2、如果定义了嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象。但如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当做垃圾回收。

    3、但是如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数,他就不会被当做垃圾回收,并且他所指向的变量绑定对象也不会被当做垃圾回收。

    结合高程,可以理解3、,因为换成代码就是这样:

    function createComparisonFunction(propertyName) {
        //并将它作为返回值返回
        return function(object1, object2) {
            var value1 = object1[propertyName];
            var value2 = object2[propertyName];
            if (value1 < value2) {
                return -1;
            } else if (value1 > value2) {
                return 1;
            } else {
                return 0;
            }
        };
    }
    
    //创建函数
    var compareNames = createComparisonFunction("name");

    createComparisonFunction()函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。这个很好理解;

    但是2、比较模糊,换成代码我觉得就是下面这样,

    function createComparisonFunction(propertyName) {
        //但如果这些嵌套的函数对象在外部函数中保存下来
        function f(object1, object2) {//嵌套的函数都各自对应一个作用域链
            var value1 = object1[propertyName];//这个作用域链指向一个变量绑定对象
            var value2 = object2[propertyName];
            if (value1 < value2) {
                return -1;
            } else if (value1 > value2) {
                return 1;
            } else {
                return 0;
            }
        }
    
        return f;
    }
    
    var compareNames = createComparisonFunction("name");

    所以问题是:
    var compareNames = createComparisonFunction("name"); 执行完了后,createComparisonFunction()的活动对象会被销毁么?

    回答1:会销毁,因为按照 2、所说,

    但如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当做垃圾回收。

    返回的 f 在 外部函数中保存下来了,所以会和所指向的变量绑定对象一样当做垃圾回收。

    回答2:不会销毁,因为返回的 f 里依然保存着对 createComparisonFunction() 活动对象的引用啊,就是那个 propertyName ,所以 createComparisonFunction() 活动对象不会销毁;

    所以哪个解释是对的?还是有其他解释?

    1
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 痛苦在呻吟 普通会员 1楼

      是的,如果嵌套的函数对象在外部函数中保存下来,它们也会被垃圾回收。这是因为JavaScript是一种动态类型的语言,也就是说,即使函数对象在内存中被保存下来,它们也可以被修改或删除。然而,这并不会改变它们和变量绑定的对象。当函数被调用时,它们会被调用对象(即外部函数)所引用的变量所绑定的对象所绑定。这是JavaScript的一种特殊机制,用于在函数调用之间保持变量的引用关系。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部