2013-06-28 1 views
4

내가 할 경우 (전역 범위에서) 다음자바 스크립트 : 이름이없는 개체는 어떻게됩니까?

var myObject = {name: "Bob"}; 

I 메모리에 객체 (즉 문자열 식별자 "인 myObject)"를 가리 할 수있는 방법이있다. 나는 콘솔과 유형 열 수 있습니다 myObject.name 및 콘솔로 응답합니다 : 난 그냥 입력하면, 이제

"Bob" 

:

{name: "Jane"}; 

을 어디 선가 그 개체를 만드는거야 나는 그것을 같은데요 어떤 범위에서 살고있다. 내가 그것을 찾을 수있는 방법이 있습니까? 일부 일반 상점에 어딘가에 window 아래에 있습니까?

편집 : 일부 사람들은 가비지 수집을한다고 말합니다.

어떻게이 예 약 : 콜백은 DOM 이벤트에 바인딩되어 있기 때문에 쓰레기 수집 할 수없는

var MyObject = function(){ 
    $("button").click(this.alert); 
} 

MyObject.prototype.alert = function(){ 
    alert("I heard that!") 
} 

new MyObject(); 

. 결과 객체는 어디에 있으며 어디에 액세스 할 수 있습니까?

+0

아니. 개체가 만들어지고 가비지 수집됩니다. 그것들과 마찬가지로 strict ";"문자열을 사용하십시오. 나도 일부 JS 엔진도 만들지 않을 수도 있습니다 – MaxArt

+0

다른 사람이 질문했지만 그들의 코멘트를 삭제했습니다.귀하의 첫 번째 예제는 당신이 생각하는 객체를 정의하는 것인가 아니면 블록, 레이블 및 문자열일까요? –

+1

업데이트에 약간의 확장 (내 생각에 컨스트럭터의 이벤트 핸들러를 바인딩하는 방법에 대한 답변이 업데이트되었습니다. 추가 할 수도 있습니다. 일반적으로 최선의 방법은 아닙니다. ( –

답변

2

짧은 답변은 아니요이며 개체는 도달 할 수없는 곳에 메모리에 보관되지 않습니다. 비트 인생은 생생합니다 : 진실은 조금 더 복잡하지만, 기본을 이해한다면 그다지 복잡하지 않습니다.

업데이트 :
귀하의 업데이트에 대한 응답으로 : 귀하는 옳은 방법입니다. 콜백은 에 대한 참조이며 this.alert을 사용하여 액세스했지만 해당 함수 객체는 생성자 프로토 타입에 의해 참조되며 어쨌든 GC'ed 될 수 없습니다. 인스턴스 자체는 alert 함수 자체에 포함되어 있지 않으므로 안전하게 GC' 될 수 있습니다. 이 같은 그것의

생각해은 :

함수 객체 자체가 직접 아무것도 연결되어 있지 않습니다
MyConstructor.prototype.alert = 0x000123;//some memory address 
    || 
    \/ 
0x00= [object Function]; 

, 그것은 메모리가 수레, 그리고 프로토 타입에 의해 참조되고있다. 다음과 같이

new MyConstructor().alert; 

가 해결 : 당신이 인스턴스를 만들 때

[new MyConstructor instance] allocated at e.g 0x000321 
    || 
    \\ 
    \=>[alert] check for alert @instance -> not found 
      \\ 
      \=> check prototype, yield 0x00<-- memory address, return this value 

그래서 문을 실행시 :

$("button").click(this.alert); 

this.alert0x000123에 해결하는 식이다. 즉, click 메서드 (함수 객체)는 alert 함수 객체의 메모리 주소 만받습니다. 인스턴스 또는 실제로 생성자가 전혀 개입되지 않습니다.따라서 this 또는 호출 컨텍스트가 함수가 호출되는 방법과 위치에 따라 변경 될 수 있습니다. see here for more on ad-hoc context determination

심지어 하나 더 잘 할 수있는 것들 :

/*assume your code is here*/ 
new MyConstructor().alert = function(){ alert('I am deaf');}; 
MyConstructor.prototype.alert = 'foo'; 
$('#button').click(); 

이 모두 같은의 프로토 타입도 관여하지 않습니다 "나는 들었다"무엇을, 경고 클릭 이벤트 맞춰,하자 혼자서 그 인스턴스.
MyConstructor이 범위를 벗어날 경우 click 이벤트는 GC가 여전히 범위를 벗어난 경고 기능 개체에 대한 참조를 계속보고 있기 때문에 계속 작동합니다. 그러나 다른 모든 것들은 GC 작업에 사용할 수 있습니다 ...


JS 가비지 컬렉터 (GC)는 플래그 앤드 와이프 GC입니다. JS 엔진이 귀하의 진술을 발견하면 에 개체를 저장하는 데 필요한 메모리를 할당합니다. 다음 문장에 도달하면 해당 객체는 여전히 메모리에 남아있을 것입니다.
때때로 GC는 메모리에있는 모든 객체를 검사하고 아직 액세스 할 수있는 객체에 대한 모든 참조를 찾습니다. 해당 문에서 방금 작성한 객체 리터럴이 있지만 참조가 할당되지 않은 경우 객체에 가비지 수집이 플래그로 지정됩니다.
다음 번에 GC에서 플래그가 지정된 개체를 스 와이프하면 해당 개체가 메모리에서 제거됩니다.

물론 이것은 의 경우 모두 엔진에 대해서는 사실이 아닙니다. 당신의 문이 인생에 기록 된 가정 그 함수 반환

var foo = function() 
{ 
    {name: 'bar'}; 
    return function() 
    { 
     return 'foobar'; 
    }; 
}()); 

일부 엔진은 바로 메모리에 인생의 전체 범위를 유지하고, 해당 범위에 대한 메모리를 할당 해제를 할 때 반환 값의 IIFE는 범위를 벗어납니다 (GC 플래그로 표시됨). 내가 점검 한 V8과 같은 다른 엔진은 실제로 반환 값으로 참조되지 않는 외부 범위의 해당 객체/변수를 표시합니다.
비록 그것에 대해 생각해 보니,이 경우에는 적용되지 않을 수도 있습니다. 왜냐하면 GC가 IIFE가 반환되기 전에 시작될 수도 있기 때문입니다 ... 그러나 전체적으로 그것은 단지 피킹에 불과합니다. 이 논리의 문제가 아니라 나 고려의

:이 경우

var name = (mayNotExist || {name:'default'}).name; 

, mayNotExist이 존재하는 경우도 생성되지 않습니다 객체 리터럴, 표현의 JS의 단락 회로 평가 덕분에 .

문제에 링크 몇 :

+0

매우 완벽한 답변을 주셔서 감사합니다. –

5

이 개체를 가리키는 참조가없는 경우 (즉, 변수 나 속성의 값에 할당하지 않은 경우) 액세스 할 수있는 방법이 없으며 실제로는 가비지 컬렉터는이 메모리를 즉시 회수 할 수 있습니다.

+2

나는 탈출했다고 생각하고 살고 싶어합니다.) 양고기. – Yatrix

+2

@Yatrix 나는 'lam'에 있다고 생각하지만 '양고기에 살기'는 더 맛있게 들린다. –

+0

@MattHarrison Hehe. 나는 결코 lam에 가지 않고있다. 그러나 내가 이제까지라면, 나는 어린 양을 가지고 있기를 바란다. 나와 함께 가져 가라. – Yatrix

관련 문제