объркване относно събирането на боклук сред затварянията

От известно време не съм сигурен относно правилата на JS събирането на боклука около затварянето, така че смятам, че може и да попитам... Ето един добър пример, за който съм любопитен относно включването на метода $.each на jQuery:

storeSelection: function() {
    var enabledIds = {};

    $.each(this.nodes, function(index, node) {
        if (node.enabled) {
            enabledIds[ node.id ] = true;
        }
    });

    this.selection = enabledIds;
}

Горният фрагмент е, разбира се, част от обектен литерал. И така, създадох нов обект в горната част на външната функция, който ще съхранява идентификаторите на разрешените елементи в масив. Използвайки метода .each() на jQuery, преминавам през масива от елементи и регистрирам активирани идентификатори. И накрая, съхранявам селекцията като член на родителския обект.

Въпросът ми включва тази вътрешна функция, която препраща към enabledIds обекта от външния обхват. Тъй като enabledIds ще остане, това пречи ли на вътрешната функция да бъде събрана? Бих предположил, че не, защото това е просто променлива, която се изчиства в края на вътрешната функция, нали? За да стане изтичане, предполагам, че вътрешната функция ще трябва да направи твърда препратка към външния обект, както в:

$.each(this.nodes, function(index, node) {
    this.badIdea = enabledIds;
    if (node.enabled) {
        enabledIds[ node.id ] = true;
    }
});

Обаче... това правило винаги ми е мъгливо. Всяка помощ за изясняване на това объркване ще бъде оценена!


person bigmac    schedule 22.05.2012    source източник


Отговори (2)


Не, дори вторият ви пример не би бил достатъчен, за да предизвика изтичане на информация. badIdea е прикрепен към отделните възли, а блокът $.each ще излезе и ще бъде събран за боклук. Всички съвременни браузъри използват алгоритъм за „маркиране и почистване“ за събиране на боклука на javascript, който следва асоциации родител към дете и събира всички „недостъпни“, т.е. всичко, което не може да бъде достъпно от едно от тези дървета.

person Chris Pratt    schedule 22.05.2012

Прав си, променливите от вътрешната функция (index, node) ще бъдат събрани за боклук, защото вече не могат да бъдат достъпни.

В този пример можете ли да получите достъп до bigstr?

a = function() {
        var bigstr = new Array(1000000).join('x');
        return function() { return bigstr; };
    }();

Да, можете: a(), така че не се събира. Какво ще кажете за този пример:

a = function() {
        var bigstr = new Array(1000000).join('x');
        return function(n) { return eval(n); };
    }();

Отново можете: a('bigstr').

Но какво да кажем за този:

a = function() {
        var smallstr = 'x';
        var bigstr = new Array(1000000).join('x');
        return function(n) { return smallstr; };
    }();

Вече нямате достъп до него и е кандидат за събиране на боклук.

person Alexey Lebedev    schedule 22.05.2012