[javascript] JavaScript 객체를 빠르게 지우는 방법은 무엇입니까?

JavaScript 배열을 사용하면 단일 할당으로 빈 상태로 재설정 할 수 있습니다.

array.length = 0;

이렇게하면 어레이가 비어 있고 재사용 할 준비가되며 하나의 “조작”즉, 일정한 시간이라는 것을 알 수 있습니다.

JS 객체를 지우는 비슷한 방법이 있습니까? 필드를 삭제하여 삭제할 수 있다는 것을 알고 있습니다.

for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }

그러나 이것은 선형적인 복잡성을 가지고 있습니다.

객체를 버리고 새 객체를 만들 수도 있습니다.

obj = {};

그러나 새 객체를 “차단 성”으로 만들면 IE6의 가비지 수집에 문제가 발생합니다. ( 여기에 설명 된대로 )



답변

귀하의 질문에 대한 짧은 대답은 아니오라고 생각합니다 (새로운 객체를 만들 수 있습니다).

  1. 이 예제에서 길이를 0으로 설정하면 여전히 가비지 수집을위한 모든 요소가 남습니다.

  2. 자주 사용하는 Object.prototype에 추가 할 수 있습니다. 그렇습니다. 복잡하게 선형 적이지만 나중에 가비지 수집을 수행하지 않는 것이 될 것입니다.

  3. 이것이 가장 좋은 해결책입니다. 귀하의 질문과 관련이 없다는 것을 알고 있습니다. 그러나 IE6 지원을 얼마나 오래 지속해야합니까? 사용을 중단하는 캠페인이 많이 있습니다.

위에 잘못된 것이 있으면 언제든지 수정하십시오.


답변

글쎄, 물건을 너무 쉽게 만들 위험이 있습니다 …

for (var member in myObject) delete myObject[member];

… 최소한 무서운 괄호를 사용하여 한 줄의 코드로 객체를 청소하는 데 꽤 효과적 인 것 같습니다. 모든 회원은 가비지로 남지 않고 실제로 삭제됩니다.

분명히 객체 자체를 삭제하려면 여전히 별도의 delete ()를 수행해야합니다.


답변

ES5

ES5 솔루션은 다음과 같습니다.

// for enumerable and non-enumerable properties
Object.getOwnPropertyNames(obj).forEach(function (prop) {
  delete obj[prop];
});

ES6

ES6 솔루션은 다음과 같습니다.

// for enumerable and non-enumerable properties
for (const prop of Object.getOwnPropertyNames(obj)) {
  delete obj[prop];
}

공연

사양에 관계없이 가장 빠른 솔루션은 일반적으로 다음과 같습니다.

// for enumerable and non-enumerable of an object with proto chain
var props = Object.getOwnPropertyNames(obj);
for (var i = 0; i < props.length; i++) {
  delete obj[props[i]];
}

// for enumerable properties of shallow/plain object
for (var key in obj) {
  // this check can be safely omitted in modern JS engines
  // if (obj.hasOwnProperty(key))
    delete obj[key];
}

for..in얕은 객체 나 일반 객체에서만 수행해야하는 이유 는 삭제 가능한 고유 속성이 아니라 프로토 타입으로 상속 된 속성을 통과하기 때문입니다. 경우 개체가 일반과 특성, 열거 것을 확실히 알려져 있지 않다 for으로 Object.getOwnPropertyNames더 나은 선택입니다.


답변

당신은 이것을 시도 할 수 있습니다. 아래 함수는 객체 속성의 모든 값을 undefined로 설정합니다. 중첩 된 객체와 함께 작동합니다.

var clearObjectValues = (objToClear) => {
    Object.keys(objToClear).forEach((param) => {
        if ( (objToClear[param]).toString() === "[object Object]" ) {
            clearObjectValues(objToClear[param]);
        } else {
            objToClear[param] = undefined;
        }
    })
    return objToClear;
};


답변

그래서 당신의 질문을 요약하면 : 가능한 한 IE6 GC 버그와 관련된 문제를 피하고 싶습니다. 이 버그에는 두 가지 원인이 있습니다.

  1. 가비지 콜렉션은 많은 할당 마다 한 번씩 발생합니다 . 따라서 할당을 많이할수록 GC가 더 자주 실행됩니다.
  2. ‘공중’에있는 오브젝트가 많을수록 가비지 콜렉션 실행에 걸리는 시간이 길어집니다 (가비지로 표시된 오브젝트를보기 위해 전체 오브젝트 목록을 크롤링하기 때문).

1을 일으키는 해결책은 다음과 같습니다. 할당 수를 줄입니다. 가능한 한 적은 새 객체와 문자열을 할당하십시오.

2를 일으키는 해결책은 다음과 같습니다. ‘실제’객체 수를 유지하십시오. 더 이상 필요하지 않은 문자열과 객체를 삭제하고 필요할 때 새로 만듭니다.

어느 정도까지는 이러한 솔루션이 모순됩니다. 메모리에있는 객체 수를 낮게 유지하려면 더 많은 할당 및 할당 해제가 수반됩니다. 반대로, 동일한 객체를 지속적으로 재사용한다는 것은 꼭 필요한 것보다 더 많은 객체를 메모리에 유지하는 것을 의미 할 수 있습니다.


이제 질문하십시오. 새 객체를 생성하거나 모든 속성을 삭제하여 객체를 재설정할지 여부는 나중에 수행하려는 작업에 따라 다릅니다.

아마도 새로운 속성을 할당하고 싶을 것입니다.

  • 그렇게하면 즉시 새 속성을 할당하고 먼저 삭제 또는 지우기를 건너 뛰는 것이 좋습니다. (그러나 모든 속성을 덮어 쓰거나 삭제 해야합니다 !)
  • 객체가 즉시 사용되지 않지만 나중에 다시 채워지면 객체를 삭제하거나 null을 할당하고 나중에 새 객체를 생성하는 것이 좋습니다.

JScript 객체를 새 객체를 만들지 않고 마치 새로운 객체 인 것처럼 재사용 할 수있는 빠르고 쉬운 방법은 없습니다. jthompson이 말하는 것처럼 귀하의 질문에 대한 짧은 대답은 ‘아니요’입니다.


답변

ES7에서 Object.observe를 기대하고 일반적으로 데이터 바인딩을 고려할 때 고려해야 할 새로운 사항. 치다:

var foo={
   name: "hello"
};

Object.observe(foo, function(){alert('modified');}); // bind to foo

foo={}; // You are no longer bound to foo but to an orphaned version of it
foo.name="there"; // This change will be missed by Object.observe()

따라서 이러한 상황에서 # 2가 최선의 선택이 될 수 있습니다.


답변

소품을 삭제할 수는 있지만 변수는 삭제할 수 없습니다. delete abc;ES5에서는 유효하지 않으며 엄격하게 사용합니다.

GC에 삭제하도록 설정하려면 null로 할당 할 수 있습니다 (속성에 대한 다른 참조가있는 경우는 아닙니다)

설정 length개체에 대한 특성은 아무것도 변경되지 않습니다. (그것은 단지 속성을 설정합니다)