2012-05-22 8 views
2

잠시 동안 폐쇄를 둘러싼 JS 쓰레기 수거의 규칙에 대해 확신이 서지 않았기 때문에 물어볼 수도 있습니다. 여기에 참여하는 것이 궁금합니다. jQuery의 $.each있어서폐쇄 간 쓰레기 수거에 대한 혼란

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

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

    this.selection = enabledIds; 
} 

상기 SNIPPIT는 물론 객체 리터럴 부분. 그래서 배열 안에 활성화 된 항목의 ID를 저장하는 외부 함수의 맨 위에 새 객체를 만들었습니다. jQuery의 .each() 메서드를 사용하여 항목 배열과 사용 가능한 ID 로깅을 반복합니다. 마지막으로 선택 항목을 부모 개체의 멤버로 저장합니다.

내 질문에는 외부 범위에서 enabledIds 개체를 참조하는 내부 함수가 관련되어 있습니다. enabledIds이 붙어 있기 때문에 내부 기능이 수집되는 것을 방지합니까? 내 함수의 끝에서 지워지는 변수 일 뿐이니까요. 그렇죠? 누수가되기 위해, 나는 내부 기능과 같이 외부 개체에 대한 하드 참조 할 필요가 가정

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

그러나 ... 난 항상이 규칙에 안개입니다. 이 혼란을 해결하는 데 도움이 될 것입니다!

답변

3

아니요, 두 번째 예도 누출이 발생하지 않을 수 있습니다. badIdea은 개별 노드에 연결되고 $.each 블록은 종료되고 가비지 수집됩니다. 모든 최신 브라우저는 javascript 가비지 수집에 "마크 및 스윕"알고리즘을 사용합니다.이 알고리즘은 부모와 자식 간의 연결을 추적하여 "도달 할 수없는"즉, 이러한 트리 중 하나에서 액세스 할 수없는 모든 것을 수집합니다.

1

맞습니다. 더 이상 액세스 할 수 없기 때문에 내부 함수 (index, node)의 변수가 가비지 수집됩니다.

이 예에서는 bigstr에 액세스 할 수 있습니까? 가 수집되지 그래서 a() :

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

을 수행 할 수 있습니다. 이 예제에 대해 무엇 : 다시

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; }; 
    }(); 

당신은 더 이상 액세스 할 수 있으며, 가비지 컬렉션의 후보입니다.