JavaScript에서 객체 삭제


359

JavaScript의 delete연산자 와 약간 혼동됩니다 . 다음 코드를 보자.

var obj = {
    helloText: "Hello World!"
};

var foo = obj;

delete obj;

이 코드 조각이 실행 된 후에 obj는 is null이지만 foo여전히 정확히 같은 객체를 참조합니다 obj. 이 객체가 foo지적한 것과 동일한 객체라고 생각 합니다.

쓰기 가 변수뿐만 아니라 메모리에서 가리키는 delete obj객체를 삭제 한다고 기대했기 때문에 이것은 혼란 스럽습니다 .objobj

이 자바 스크립트의 쓰레기 때문에 콜렉터가 나는 물체를 가리키는 다른 변수를 가지고 있지 않은 경우, 그것은 그래서하는 유지 / 해제를 기준으로하고있다인가 것이다 메모리에서 제거?

(제 테스트는 Safari 4에서 수행되었습니다.)





1
@Steve Harrison delete는 자바 스크립트에서 객체를 삭제하기위한 var obj = { helloText: "Hello World!" }; var foo = obj; delete obj;것이 아닙니다. 귀하의 경우 객체 키를 제거하기위한 삭제 사용 객체가 삭제되지 않았는지 확인 obj: 사용법 delete obj.helloText을 확인한 다음 확인foo now foo is an empty object
Umair Ahmed

2
@UmairAhmed, Free translation : "" " delete는 자바 스크립트에서 객체를 삭제하는 것이 아닙니다. delete객체 키를 제거하는 데 사용됩니다. 귀하의 경우 var obj = { helloText: "Hello World!" }; var foo = obj; delete obj;에는 객체가 삭제되지 않습니다. 확인 obj. 다음, 실행 delete obj.helloText하면 foo이제 비어 있음을 알 수 있습니다 "" "
Pacerier

답변:


448

delete 연산자는 객체 자체가 아닌 참조 만 삭제합니다. 객체 자체를 삭제 한 경우 C ++ 삭제와 같이 다른 나머지 참조는 매달려 있습니다. (둘 중 하나에 액세스하면 충돌이 발생합니다. 모두 널 (null)로 설정하면 각 오브젝트에 대해 메모리를 추가하거나 삭제할 때 추가 작업이 필요합니다.)

Javascript는 가비지 수집되므로 객체 자체를 삭제할 필요가 없습니다. 더 이상 참조 할 방법이 없으면 객체가 제거됩니다.

가비지 수집기에서 회수 할 수있는 항목에 대한 자세한 정보를 제공하므로 개체에 대한 참조를 완료하면 객체에 대한 참조를 삭제하는 것이 유용 할 수 있습니다. 참조가 큰 객체에 남아 있으면 프로그램의 나머지 부분에서 실제로 해당 객체를 사용하지 않더라도 참조가 회수되지 않을 수 있습니다.


23
delete키워드는 객체의 속성이 아닌 변수를 사용할 수 있습니다. perfectionkills.com/understanding-delete
Alex Mund

1
@AlexJM 예, Guffa (및 의견)의 다음 답변은 이에 대해 자세히 설명합니다.
Jesse Rusak

1
객체의 속성은 다른 객체 일 수 있습니다. 예를 들어; var obj = {a: {}}; delete obj.a;
Alex Mund

2
그러나 ... 변수가 실제로 속성이 window아닌가?
RedClover

3
@Soaku는 지역 변수가 아닙니다. (사람들은 선언 EG var)
제시 Rusak에게

162

delete명령은 일반 변수에는 영향을 미치지 않으며 속성에만 영향을줍니다. delete명령 후에 속성에 값 null이 없으면 전혀 존재하지 않습니다.

특성이 객체 참조 인 경우 delete명령은 특성을 삭제하지만 오브젝트는 삭제하지 않습니다. 가비지 수집기는 개체에 대한 다른 참조가없는 경우 개체를 처리합니다.

예:

var x = new Object();
x.y = 42;

alert(x.y); // shows '42'

delete x; // no effect
alert(x.y); // still shows '42'

delete x.y; // deletes the property
alert(x.y); // shows 'undefined'

(Firefox에서 테스트되었습니다.)


39
이것이 전역 범위에서 실행 x되면 변수는 전역 window객체 의 속성이 되고 delete x;실제로 x변수를 모두 제거 합니다.
Crescent Fresh

18
@crescentfresh : 암시 적으로 선언 된 경우에만 속성입니다. 예제와 같이 명시 적으로 선언 된 경우 전역 변수이므로 삭제할 수 없습니다.
Guffa

4
@Tarynn : 문제가있는 곳입니다. 콘솔에서이 작업을 수행하면 어떤 이유로 x일부 브라우저에서는 적절한 변수가 아니라 window개체 의 속성이됩니다 . 이것은 물론 콘솔의 문제이며 코드가 정상적으로 실행되는 방식을 반영하지 않습니다.
Guffa

2
@Guffa 많은 연구 끝에 나는 투표를 거부 할 충분한 담당자가 없었을 것이라는 것을 인정해야합니다. 진심으로 사과와 시간을내어 무슨 일이 있었는지 보여 주셔서 감사합니다 ... 여기에 자세한 설명이 있습니다. perfectionkills.com/understanding-delete/#firebug_confusion
Tarynn

2
@chao : 알겠습니다. Tarynn과 동일한 문제가 있습니다 (이전 설명 참조). 콘솔 에서이 작업을 수행하면 실제 코드와 동일하게 작동하지 않습니다.
Guffa

56

"암시 적으로 선언 된 변수"는 전역 객체의 속성이므로 모든 속성에서 작동하는 것처럼 delete 작동합니다. var로 선언 된 변수는 파기 할 수 없습니다.


53
나는 var가 그렇게 나쁜 것을 깨닫지 못했습니다.
Gavin

1
이것은 좋은 지적이며 JS가 있습니다. 사람들은 창 변수를 삭제하는 데 익숙해지고 지역 변수로 왜 그렇게 할 수 없는지 궁금합니다.
welbornio

2
동일합니다 let.
Pacerier


4

delete Java Script에서 객체를 삭제하는 데 사용되지 않습니다.

deleteobject key귀하의 경우 에 제거에 사용

var obj = { helloText: "Hello World!" }; 
var foo = obj;
delete obj;

객체가 삭제되지 않았는지 확인하십시오 .obj는 여전히 동일한 값을 사용합니다.

delete obj.helloText

확인 obj, foo하고 둘 다 빈 객체입니다.


2

이 문제에 비추어 흥미로운 것으로 생각 되는 jsperf 를 발견했습니다 . (사진을 완성하기 위해 보관하는 것이 편리 할 수 ​​있습니다)

delete , null 설정 및 undefined 설정을 비교합니다 .

그러나 속성을 여러 번 삭제 / 설정 한 경우를 테스트한다는 점에 유의하십시오.



1

IE 5 ~ 8에는 호스트 개체 (Window, Global, DOM 등)의 속성에 대해 delete를 사용하면 TypeError "object가이 작업을 지원하지 않습니다"가 발생하는 버그가 있습니다.

var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
    delete el.foo;
}catch(){
    //alert("Curses, drats and double double damn!");
    el.foo=undefined; // a work around
}

나중에 IE에서 항상 true를 반환 하기 el.foo !== undefined때문에 속성에 전체 값 사용의 의미가 있는지 확인 해야하는 경우 "foo" in el.

만약 당신이 정말로 사라질 부동산이 필요하다면 ...

function hostProxy(host){
    if(host===null || host===undefined) return host;
    if(!"_hostProxy" in host){
       host._hostproxy={_host:host,prototype:host};
    }
    return host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};

delete el.foo; // removing property if a non-host object

호스트 객체와 함께 호스트 객체를 사용해야하는 경우 ...

el.parent.removeChild(el._host);

1

나는이 같은 대답을 찾기 위해이 기사를 우연히 발견했다. 내가 한 일은 obj.pop()객체에 저장된 모든 값 / 객체를 튀어 나와 객체를 재사용하는 것입니다. 이것이 나쁜 습관인지 아닌지 확실하지 않습니다. 이 기술은 Chrome Dev 도구 또는 FireFox 웹 콘솔에서 코드를 테스트하는 데 유용했습니다.


1

좋은 습관은 아니지만이 작업은 저에게 효과적입니다. 단순히 객체가 속한 모든 관련 요소를 삭제합니다.

 for (element in homeService) {
          delete homeService[element];
  }

모범 사례는 무엇입니까? 삭제 연산자가 객체 속성을 삭제하는 데 가장 적합하지 않다는 것을 기억합니다. 나는 Crockford의 JavaScript 책에서 이것을 읽었지만 지금은 그것을 읽을 수 없다고 생각합니다.
zero_cool

0

변수를 설정 null하여 DOM 요소와 Javascript 범위간에 순환 참조를 포함하여 모든 브라우저에서 객체에 대한 참조를 분리 할 수 ​​있습니다. delete명령 을 사용하여 가비지 콜렉션의 다음 실행에서 오브젝트가 지워지도록 표시하지만 동일한 오브젝트를 참조하는 여러 변수가있는 경우 단일 변수를 삭제하면 해당 오브젝트를 해제하지 않고 해당 변수와 그 물체. 그리고 다음에 가비지 콜렉션을 실행할 때 변수 만 정리됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.