JavaScript 객체에서 속성을 어떻게 제거합니까?


6139

다음과 같이 객체를 생성한다고 가정 해보십시오.

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

다음과 같이 regex새 속성 으로 끝나는 속성 을 제거하는 가장 좋은 방법은 무엇입니까 myObject?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};


@EscapeNetscape 이것은 행동에 관한 질문이므로 벤치 마크에서 잘못된 그림을 그립니다. 물론 delete간단한 할당 인 다른 두 가지보다는 실제 작업이기 때문에 가장 느린 옵션입니다. 그러나 문제의 핵심은 속성을 객체에 할당 null하거나 undefined실제로 객체에서 속성을 제거하지 않고 그 속성을 특정 상수 값과 동일하게 설정한다는 것입니다. (대답 아래에 이것이 중요한 차이점이있는 이유가 나와 있습니다.)
Abion47

답변:


8299

이처럼 :

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

데모

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

더 그것에 대해 독서에 관심있는 사람들을위한, 스택 오버플로 사용자 kangax는 [정보] 믿을 수 없을만큼 깊이있는 블로그 게시물 작성했습니다 delete, 자신의 블로그에 문을 삭제 이해 . 적극 권장합니다.


47
또한 "delete myJSONObject [ 'regex'];"와 함께 작동합니다. 참조 : developer.mozilla.org/en/Core_JavaScript_1.5_Reference/...
johnstok

109
위의 "삭제 이해"링크에서 관찰 중 하나의 결과는 변수를 삭제할 수는 없지만 객체 속성 만 삭제할 수 있기 때문에 "참조로"객체 속성을 삭제할 수 없다는 것입니다. var value = obj [ '소품']; 값 삭제 // 작동하지 않음
Dexygen

27
실제로 삭제하지 않습니까? 정의되지 않았지만 키가 여전히 존재합니까? 뭔가 빠졌습니까?
Doug Molineux

151
@Pete 아니오, 제거합니다. 주어진 : var x = {a : 'A', b : 'B'};비교 : delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */tox.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf

16
@ChristopherPfohl이 나를 위해 일합니다. 내가 말했듯이, 실제로는 매우 심층적이므로 요약하기가 약간 어렵습니다. 위의 답변에 대한 기본 답변은 거의 모든 경우에 충분하며 블로그는 더 많은 경우와 그 경우가 존재하는 이유에 대해 설명합니다.
nickf December

952

JavaScript의 객체는 키와 값 사이의 맵으로 생각할 수 있습니다. delete오퍼레이터는 흔히 객체 속성 한번에 하나로 알려진 이러한 키를 제거하는데 사용된다.

var obj = {
  myProperty: 1    
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false

delete운전자는 직접적으로 사용 가능한 메모리 않으며, 단순히 값을 할당 상이 null하거나 undefined속성 것을에서는, 속성 자체가 개체로부터 제거된다. 삭제 된 속성 의 이 참조 유형 (객체)이고 프로그램의 다른 부분이 여전히 해당 객체에 대한 참조를 보유하는 경우 해당 객체에 대한 모든 참조가있을 때까지 해당 객체는 가비지 수집되지 않습니다. 사라졌다.

delete 디스크립터가 구성 가능으로 표시 한 특성에서만 작동합니다.


43
undefined에 할당 된 속성은 여전히 ​​객체의 속성이므로 마지막 단락을 잘못 읽지 않는 한 GC에 의해 제거되지 않습니다.
랜스

8
나는 여기서 GC의 주제를 다루는 것이 잘못되었다. 두 방법 모두 GC에 대해 동일한 결과를 갖습니다. 키에 연결된 값을 제거합니다. 해당 값이 다른 객체에 대한 마지막 참조 인 경우 해당 객체가 정리됩니다.
Dan

15
undefined에 할당 된 속성은 여전히 ​​객체의 속성이므로 GC에 의해 제거 되지 않습니다. GC는 속성에 대해 아무것도 관리하지 않습니다. 값을 수집하고 제거합니다. 더 이상 값 (객체, 문자열 등)을 참조하는 것이 없으면 GC는 메모리에서 값을 제거합니다.
meandre

8
BTW, Javascript 객체에 속성이 있는지 확인하는 이중 문제입니다. in 연산자를 사용 하면 안정적이지만 느립니다. 속성이 정의되어 있지 않은지 "정답이 아닌지" 확인하십시오 . 점검
rdllopes

8
이 답변은 여전히 ​​관련이 있습니까? jsperf 현재 다운하지만 이 벤치 마크는 속도 차이는 어디에도 불과 25 % 인 것을 나타내는 것 같다 가까운 받는 "~ 100 배 느린" 이 대답한다.
Cerbrus

248

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

이것은 Firefox 및 Internet Explorer에서 작동하며 다른 모든에서도 작동한다고 생각합니다.


216

delete연산자 오브젝트에서 속성을 제거하기 위해 사용된다.

const obj = { foo: "bar" }
delete obj.foo
obj.hasOwnProperty("foo") // false

배열의 경우 이것은 element를 제거하는 것과 다릅니다 . 어레이에서 사용하는 요소를 제거 Array#splice하거나 Array#pop. 예를 들면 다음과 같습니다.

arr // [0, 1, 2, 3, 4]
arr.splice(3,1); // 3
arr // [0, 1, 2, 4]

세부

deleteJavaScript에서는 C 및 C ++의 키워드와 다른 기능을합니다. 메모리를 직접 비우지 않습니다. 대신 유일한 목적은 객체에서 속성을 제거하는 것입니다.

배열의 경우 인덱스에 해당하는 속성을 삭제하면 희소 배열 (예 : "구멍"이있는 배열)이 생성됩니다. 대부분의 브라우저는 이러한 누락 된 배열 인덱스를 "비어 있음"으로 나타냅니다.

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

참고 delete재배치하지 않습니다 array[3]array[2].

JavaScript의 다른 내장 함수는 희소 배열을 다르게 처리합니다.

  • for...in 빈 인덱스를 완전히 건너 뜁니다.

  • 전통적인 for루프는 undefined인덱스 값을 반환 합니다.

  • 사용하는 모든 메소드 는 색인에서 값을 Symbol.iterator리턴 undefined합니다.

  • forEach, map그리고 reduce단순히 누락 된 인덱스를 건너 뜁니다.

따라서 delete연산자를 배열에서 요소를 제거하는 일반적인 사용 사례에 사용해서는 안됩니다. 배열 요소를 제거하고 메모리를 재 할당하기위한 전용의 방법이있다 : Array#splice()Array#pop.

배열 #splice (start [, deleteCount [, item1 [, item2 [, ...]]]])

Array#splice배열을 변경하고 제거 된 인덱스를 반환합니다. deleteCount요소는 index start에서 제거되고 index item1, item2... itemN에서 배열에 삽입됩니다 start. deleteCount생략 하면 startIndex의 요소가 배열 끝까지 제거됩니다.

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

비슷한 이름 만 다른, 기능에도있다 Array.prototype: Array#slice.

배열 # 슬라이스 ([begin [, end]])

Array#slice는 비파괴 적이며 표시된 인덱스를 포함하는 새 배열을 startto 에서 반환합니다 end. 경우 endIS는 배열의 마지막에 지정, 기본값을 떠났다. 경우 end긍정적, 그것은 제로로부터 지정 비 포함 에서 중지하는 인덱스를. 경우 end네거티브 그것은, 그것은 배열의 끝에서 다시 계산하여 정차로 인덱스를 지정 (예. -1 최종 인덱스를 생략한다). 인 경우 end <= start결과는 빈 배열입니다.

let a = [0,1,2,3,4]
let slices = [
    a.slice(0,2),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ]

//   a           [0,1,2,3,4]
//   slices[0]   [0 1]- - -   
//   slices[1]    - - - - -
//   slices[2]    - -[3]- -
//   slices[3]    - -[2 4 5]

배열 # 팝

Array#pop배열에서 마지막 요소를 제거하고 해당 요소를 반환합니다. 이 작업은 배열의 길이를 변경합니다.


12
이 방법은 다른 곳에서 여전히 참조 될 수있는 원본 객체를 수정하지 않습니다. 사용 방법에 따라 문제가 될 수도 있고 아닐 수도 있지만 명심해야합니다.
Tamas Czinege

19
@ B1KMusic 배열에서 요소를 삭제하는 방법은 다음과 같습니다. splice
wulftone

3
@wulftone nope, 배열을 분할하고 값을 삭제하지 않습니다. 특정 값을 삭제 해야하는 배열에서 삭제하는 가장 좋은 방법 delete은 가비지 수집 기능을 사용하여 정리하는 것입니다.
Braden Best

5
splice편집 한 내용은 보이지 않지만 다음과 removeArray.prototype.remove = function(index) { this.splice(index, 1); };
같아야

1
이 기사는 황소 1로 가득합니다. 질문을 다루지 않습니다! 2. 그것은 언어의 오용을 예시하고 "작동하지 않는다"고 불평하는 것이다. 3. 빈 배열 인덱스에 대해 null 을 넣는 Crockford의 고유 오류에 대해서는 JavaScript 삭제 연산자를 비난하지 마십시오 . 그는 null의 의미를 이해하지 못합니다-실수라고 생각합니다. 실수는 자신의 것입니다-주어진 배열 인덱스의 삭제 된 값에는 null이 없습니다. 배열에는 "구멍"이 없습니다. 이것은 빈 인덱스입니다. 절대적으로 합법적이고 예상됩니다.
Bekim Bacaj

195

오래된 질문, 현대적인 답변. ECMAScript 6 기능인 객체 파괴를 사용하면 다음 과 같이 간단합니다.

const { a, ...rest } = { a: 1, b: 2, c: 3 };

또는 질문 샘플의 경우 :

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);

Babel 시험판 편집기에서 작동중인 것을 확인할 수 있습니다.


편집하다:

동일한 변수에 다시 할당하려면 다음을 사용하십시오 let.

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);

6
어쩌면 목표는 객체에서 속성을 제거하고 속성이없는 새 속성을 생성하지 않는 것입니다 ...하지만 불변의 방법을 선호하므로 솔루션이 가장 좋아합니다.
Vingt_centimes

8
질문은 " 새로운 myObject 로 끝날 것"이라고 언급했다 .
코엔.

1
속성을 제거하기 위해 밑줄을 추가하면 프로젝트가 흩어집니다 :) regex다른 변수 (예 _: 결과를 버릴 수있는 Go와 같은 언어에서 사용되는 변수)에 할당 할 수 있으므로 대신 사용할 수 있습니다 const { regex: _, ...newObject } = myObject;.
코엔.

2
@PranayKumar이 구문이 효과가 있기를 바랐습니다. const { [key], ...newObject } = myObject;그러나 그것은 그렇지 않으므로 파괴가 가능하다고 생각하지 않습니다.
코엔.

2
로 다음 freeze()'D 및 seal()'D 객체, 당신은 단순히 수없는 delete속성은. 따라서 이것은 훌륭한 대안입니다. 대부분의 경우, 어쨌든 고정 / 밀봉 된 개체에서 속성을 삭제하는 것은 이치에 맞지 않을 것입니다. 요점은이 패턴이 손상 될 수있는 데이터 구조에 대해 특정 보증을하는 것입니다. 비파괴 적으로 객체를 제거해야하지만 일부 속성이없는 경우에는 완벽합니다.
Braden Best

118

확산 구문 (ES6)

그것을 필요로하는 사람에게는 ...

이 스레드에서 @Koen 답변을 완료하려면 스프레드 구문을 사용하여 동적 변수를 제거하려면 다음과 같이하십시오.

const key = 'a';
        
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(foo);  // 1
console.log(rest); // { b: 2, c: 3 }

* foo는 값 a이 1 인 새 변수입니다 .


확장 된 답변 😇
객체에서 속성을 제거하는 일반적인 방법은 거의 없습니다.
각각에는 자체 장단점 있습니다 ( 이 성능 비교를 확인하십시오 ).

연산자 삭제
읽기 쉽고 짧은 성능이지만 성능이 최적화되지 않았기 때문에 많은 수의 개체에서 작업하는 경우 최선의 선택이 아닐 수 있습니다.

delete obj[key];


재 할당
보다 2 배 이상 빠르지 만delete속성이삭제되지 않고반복 될 수 있습니다.

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


Spread Operator
ES6연산자를 사용하면 기존 객체를 변경하지 않고 속성을 제외한 완전히 새로운 객체를 반환 할 수 있습니다. 단점은 위의 성능이 저하되어 한 번에 많은 속성을 제거해야 할 때 사용하지 않는 것입니다.

{ [key]: val, ...rest } = obj;

2
여러 리터럴 엔진이 이미 구현했지만 객체 리터럴의 스프레드 / 나머지 구문은 ES6이 아닌 ES2018 (ES9)에만 포함되어 있다고 생각합니다.
trincot

2
@trincot 2014 년에 처음 소개되었으며 ( github.com/tc39/proposal-object-rest-spread ) ES6 (ECMAScript 2015 일명 ECMAScript 6th Edition) 기능입니다. 그러나 내가 틀리더라도 대답의 맥락에 차이가 있다고 생각하지 않습니다.
Lior Elrom 21

2
링크는 실제로 배열에 대해 확산 구문이 도입 된 ES6을 참조하지만 객체 리터럴과 유사한 것을 계속 제안합니다. 내가 실수하지 않으면 두 번째 부분은 ES9에만 통합되었습니다.
trincot

98

또 다른 대안은 Underscore.js 라이브러리 를 사용하는 것 입니다.

참고 _.pick()_.omit() 직접 원래 객체를 수정하지 않는 모두 반환 개체의 복사본합니다. 원래 객체에 결과를 할당하면 트릭을 수행해야합니다 (표시되지 않음).

참조 : link _.pick (object, * keys)

허용 된 키 (또는 유효한 키 배열)의 값만 갖도록 필터링 된 객체의 복사본을 반환합니다.

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

참조 : link _.omit (object, * keys)

차단 된 키 (또는 키 배열)를 생략하도록 필터링 된 객체의 복사본을 반환합니다.

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

배열의 경우 _.filter()_.reject()유사한 방식으로 사용할 수 있습니다.


4
개체의 키는 숫자가있는 경우, 당신이해야 할 수도 있다는 사실을 숙지_.omit(collection, key.toString())
요르단 Arseno

흠 .... 밑줄은 ~ 100x 느리지 만 delete obj[prop]~ 100x 느립니다 obj[prop] = undefined.
Jack Giffin

52

질문 제목에 사용한 용어 Remove a property from a JavaScript object는 몇 가지 다른 방식으로 해석 될 수 있습니다. 하나는 메모리 전체를 제거하고 객체 키 목록을 제거하는 것이고 다른 하나는 객체에서 제거하는 것입니다. 다른 답변에서 언급했듯이 delete키워드가 주요 부분입니다. 다음과 같은 객체가 있다고 가정 해 봅시다.

myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

당신이 할 경우 :

console.log(Object.keys(myJSONObject));

결과는 다음과 같습니다.

["ircEvent", "method", "regex"]

다음과 같이 객체 키에서 특정 키를 삭제할 수 있습니다.

delete myJSONObject["regex"];

그런 다음 사용하는 객체 키 Object.keys(myJSONObject)는 다음과 같습니다.

["ircEvent", "method"]

그러나 요점은 메모리에 관심이 있고 객체가 메모리에서 완전히 제거되도록하려면 키를 삭제하기 전에 null로 설정하는 것이 좋습니다.

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

여기서 중요한 또 다른 요점은 동일한 객체에 대한 다른 참조에주의해야합니다. 예를 들어 다음과 같은 변수를 만드는 경우

var regex = myJSONObject["regex"];

또는 다음과 같은 다른 객체에 대한 새 포인터로 추가하십시오.

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

그런 다음 객체에서 객체를 제거하더라도 변수에 값이 myJSONObject있기 때문에 특정 객체가 메모리에서 삭제되지 않습니다 . 그렇다면 어떻게 메모리에서 객체를 제거 할 수 있을까요?regexmyOtherObject["regex"]

대답은하는 것 바로 그 객체가 가리키는 코드에서 당신이 가진 모든 참조를 삭제 하고도 사용하지 var해당 개체에 대한 새로운 참조를 생성하는 문을 . var명령문에 관한 마지막 요점은 명령문을 사용 var하면 작성된 오브젝트가 제거되지 않기 때문에 일반적으로 직면하는 가장 중요한 문제 중 하나입니다 .

이는이 경우 명령문을 regex통해 변수를 작성 했으므로 다음 var과 같은 경우 해당 오브젝트를 제거 할 수 없음을 의미합니다 .

delete regex; //False

결과는입니다 false. 이는 예상 한대로 delete 문이 실행되지 않았 음을 의미합니다. 그러나 이전에 해당 변수를 작성하지 않았고 myOtherObject["regex"]기존의 마지막 참조 로만 사용 했다면 다음과 같이 제거하면됩니다.

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

즉, 코드에 해당 객체를 가리키는 참조가 남아 있지 않으면 JavaScript 객체가 종료됩니다.


업데이트 : @AgentME 덕분에 :

속성을 삭제하기 전에 null로 설정하면 아무것도 달성되지 않습니다 (객체가 Object.seal에 의해 봉인되어 있고 삭제가 실패하지 않는 한, 특별히 시도하지 않는 한 일반적으로 그렇지 않습니다).

자세한 정보를 얻으려면 Object.seal: Object.seal ()


잘못되었습니다-객체 만 JavaScript에서 참조로 전달되므로 myJSONObject.regex의 값이 문자열이고 다른 객체에 할당하면 다른 객체 에이 값의 사본이 있습니다.
Michał Perłakowski

당신은 옳으며 이것은 "동일한 객체에 대한 다른 참조에주의"하는 인용입니다.
Mehran Hatami 2012 년

43

ECMAScript 2015 (또는 ES6)는 내장 된 Reflect 와 함께 제공됩니다 객체 됩니다. 대상 객체와 속성 키를 매개 변수로 사용하여 Reflect.deleteProperty () 함수를 호출하여 객체 속성을 삭제할 수 있습니다 .

Reflect.deleteProperty(myJSONObject, 'regex');

이는 다음과 같습니다.

delete myJSONObject['regex'];

그러나 객체의 속성을 구성 할 수 없으면 deleteProperty 함수 나 delete 연산자를 사용하여 삭제할 수 없습니다.

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze () 는 객체의 모든 속성을 구성 할 수 없게 만듭니다 (다른 것 외에도). deletePropertyfunction ( delete operator )은 false속성을 삭제하려고 할 때 반환 합니다. 속성을 구성 할 수 있으면 반환true 수 있으면 속성이없는 경우에도를 합니다.

엄격 모드를 사용할 때 delete와 차이점은 다음 과 deleteProperty같습니다.

"use strict";

let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted

1
@Gothdo는 특히 기능적인 일을해야 할 때 더 많은 이점을 제공합니다. 예 : 당신은, 변수에 기능을 할당 인수 또는 사용으로 전달할 수 있습니다 apply, call, bind... 기능
madox2

41

다음과 같은 객체가 있다고 가정하십시오.

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

객체 속성 삭제

전체 staff배열 을 사용하려면 이를 수행하는 올바른 방법은 다음과 같습니다.

delete Hogwarts.staff;

또는 다음을 수행 할 수도 있습니다.

delete Hogwarts['staff'];

마찬가지로 전체 학생 배열을 제거하는 작업은 delete Hogwarts.students;또는 을 호출하여 수행됩니다 delete Hogwarts['students'];.

배열 인덱스 삭제

이제 단일 직원이나 학생을 제거하려는 경우 두 속성이 모두 배열이므로 절차가 약간 다릅니다.

직원의 색인을 알고 있다면 간단히 다음과 같이 할 수 있습니다.

Hogwarts.staff.splice(3, 1);

색인을 모르는 경우 색인 검색도 수행해야합니다.

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

노트

기술적 delete으로 배열에 사용할 수 있지만 배열을 사용하면 Hogwarts.staff.length나중에 예를 들어 호출 할 때 잘못된 결과가 나타납니다 . 즉, delete요소를 제거하지만 length속성 값을 업데이트하지 않습니다 . 를 사용하면 delete인덱싱이 엉망이됩니다.

따라서 객체에서 값을 삭제할 때는 항상 객체 속성을 처리하는지 또는 배열 값을 처리하는지 여부를 고려하고이를 기반으로 적절한 전략을 선택하십시오.

이것을 실험하고 싶다면 이 바이올린 을 시작점으로 사용할 수 있습니다 .


나는 항상 splice배열 대신에 사용해야한다고 생각합니다 delete.
Joel Trauger

@JoelTrauger : 그게 내가 말하는거야 ;-)
John Slegers

예. 내 의견은 그 delete조차도해서는 안된다는 것입니다. 그것의는 splice영업 찾고 있었던 것입니다.
Joel Trauger

1
@JoelTrauger : 설명하려고 할 delete때 객체 속성과 splice배열 요소에 사용해야합니다 .
John Slegers

스플 라이스는 정말 느립니다. delete배열 대신 사용해야하지만 코드를 중심으로 코드를 작성하지 않는 것이 가장 좋습니다.
Jack Giffin

39

ES6 사용 :

(파괴 + 확산 연산자)

const myObject = {
    regex: "^http://.*",
    b: 2,
    c: 3
};
const { regex, ...noRegex } = myObject;
console.log(noRegex); // => { b: 2, c: 3 }

나는 이것이 ES6 기능이라고 생각하지 않지만 ES9에만 포함 된 기능이라고 생각합니다.
trincot

그래서 실제로는 ES9 ... ;-) 당신이 쓰는대로, ES6를 사용하지만,하지 않습니다
trincot

2
이것은 객체에서 속성을 제거하는 것이 아니라 해당 속성없이 새 객체를 만드는 것입니다.
Jordi Nebot

32

개인적으로 Underscore.js 또는 Lodash 를 사용 하여 객체 및 배열 조작을 수행합니다.

myObject = _.omit(myObject, 'regex');


29

속성없이 객체를 복제하려면 :

예를 들면 다음과 같습니다.

let object = { a: 1, b: 2, c: 3 };   

그리고 'a'를 삭제해야합니다.

1. 명시 적 소품 키로 :

const { a, ...rest } = object;
object = rest;

2. 가변 소품 키 :

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3. 쿨 화살표 기능 😎 :

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);

4. 여러 속성

const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

용법

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

또는

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

1
매끄러운 화살표 기능!
JSilv

27

사용하여 삭제 방법은 MDN 설명에 따라, delete 연산자는 객체의 속성을 제거, 그렇게 할 수있는 가장 좋은 방법입니다. 따라서 간단하게 작성할 수 있습니다.

delete myObject.regex;
// OR
delete myObject['regex'];

delete 연산자는 객체에서 지정된 속성을 제거합니다. 성공적으로 삭제되면 true를 반환하고, 그렇지 않으면 false를 반환합니다. 그러나 다음 시나리오를 고려해야합니다.

  • 삭제하려는 속성이 존재하지 않으면 삭제는 아무런 영향을 미치지 않으며 true를 반환합니다.

  • 동일한 이름을 가진 속성이 객체의 프로토 타입 체인에 존재하면 삭제 후 객체는 프로토 타입 체인의 속성을 사용합니다 (즉, 삭제는 자신의 속성에만 영향을 미칩니다).

  • var로 선언 된 속성은 전역 범위 나 함수 범위에서 삭제할 수 없습니다.

  • 따라서 delete는 전역 범위에서 함수를 삭제할 수 없습니다 (이것이 함수 정의에 속하는지 함수 (식)에 있는지).

  • 객체의 일부인 기능 (
    글로벌 범위 제외)은 delete로 삭제할 수 있습니다.

  • let 또는 const로 선언 된 속성은 정의 된 범위에서 삭제할 수 없습니다. 구성 할 수없는 속성은 제거 할 수 없습니다. 여기에는 Math, Array, Object와 같은 내장 객체의 속성과 Object.defineProperty ()와 같은 메서드를 사용하여 구성 할 수없는 속성이 포함됩니다.

다음 스 니펫은 또 다른 간단한 예를 제공합니다.

var Employee = {
      age: 28,
      name: 'Alireza',
      designation: 'developer'
    }
    
    console.log(delete Employee.name);   // returns true
    console.log(delete Employee.age);    // returns true
    
    // When trying to delete a property that does 
    // not exist, true is returned 
    console.log(delete Employee.salary); // returns true

더 많은 정보를보고 더 많은 예를 보려면 아래 링크를 방문하십시오.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete


22

를 사용하는 다른 솔루션 Array#reduce.

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

그러나 원본 객체 는 변경 됩니다 . 없이 새 객체를 만들려면지정된 키 같이 reduce 함수를 새 변수에 할당하십시오.

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);


21

이 게시물은 매우 오래되어 매우 유용하므로 다른 사람 이이 게시물을보고 PHP 설정되지 않은 함수에서 왜 그렇게 간단하지 않은지 생각한 경우에 작성한 설정되지 않은 기능을 공유하기로 결정했습니다.

이 새로운 unset함수 를 작성하는 이유 는이 hash_map에 다른 모든 변수의 인덱스를 유지하기 위해서입니다. 다음 예제를보고 hash_map에서 값을 제거한 후 "test2"의 색인이 어떻게 변경되지 않았는지보십시오.

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}

20

여기에 좋은 대답이 많이 있지만 delete를 사용하여 JavaScript에서 속성을 제거 할 때 오류를 방지하기 위해 해당 속성이 있는지 먼저 확인하는 것이 현명합니다.

예 :

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

JavaScript의 동적 특성으로 인해 속성의 존재 여부를 모르는 경우가 종종 있습니다. && 앞에 obj가 있는지 확인하면 정의되지 않은 객체에서 hasOwnProperty () 함수를 호출하여 오류가 발생하지 않습니다.

이것이 특정 사용 사례에 추가되지 않은 경우 죄송하지만 객체 및 해당 속성을 관리 할 때이 디자인이 적합하다고 생각합니다.


2
bar가 존재하지 않아도 delete foo.bar가 작동하므로 테스트가 너무 많습니다 (IMHO).
PhiLho 2016 년

JavaScript를 실행하는 위치에 따라 @PhiLho Node.js에서는 이것이 서버 충돌을 유발한다고 생각합니다.
Willem

2
delete foo.bar;foo가 거짓이거나 엄격 모드에 있고 foo가 구성 할 수없는 막대 속성을 가진 객체 인 경우에만 예외를 발생시킵니다.
Macil

나는 이것에 관한 정확한 문제를 기억하지 못하지만 foo 자체가 존재하지 않고 속성을 삭제하려고 할 때 문제가 나타날 수 있다고 생각합니다.
Willem

예, foo가 존재하는지 테스트해야합니다. 그렇지 않으면 foo.bar에서 예외가 발생하지만 bar를 삭제하기 전에 존재 여부를 확인할 필요는 없습니다. 그것은 내 의견의 "너무 많은"부분입니다. :-)
PhiLho

16

ramda # dissoc 을 사용 하면 속성이없는 새로운 객체를 얻게됩니다 regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

다른 기능을 사용하여 동일한 효과를 얻을 수 있습니다-생략, 선택, ...


15

다음 방법을 시도하십시오. Object속성 값을에 할당하십시오 undefined. 그런 다음 stringify객체와 parse.

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);


1
또한JSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy

12

객체에 깊게 중첩 된 속성을 삭제하려면 속성에 대한 경로와 함께 두 번째 인수로 다음과 같은 재귀 함수를 사용할 수 있습니다.

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

예:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}

이 함수는 매력처럼 작동하지만 왜 true를 반환하고 false를 반환해야합니까? 내 코드 버전은 codepen.io/anon/pen/rwbppY 입니다. 어떤 경우에도 내 버전이 실패합니까?

@ witty2017 실패하지 않습니다. 내가 함수를 사용한 장소도 속성이 이미 있는지 여부를 확인해야했습니다. 속성이 존재하지 않으면 false를 반환합니다. 속성을 찾아서 삭제하면 true를 반환합니다.
ayushgp

8

delete키워드를 사용하여 객체의 속성을 간단히 삭제할 수 있습니다 .

예를 들면 다음과 같습니다.

var obj = {key1:"val1",key2:"val2",key3:"val3"}

속성을 제거하려면 다음과 같이 키워드를 key1사용하십시오 delete.

delete obj.key1

또는 배열과 같은 표기법을 사용할 수도 있습니다.

delete obj[key1]

참조 : MDN .


8

Object.assign () 및 Object.keys () 및 Array.map ()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);


7

'삭제'가 매우 느리고 그가 게시 한 벤치 마크에 대한 Dan의 주장은 의심 스럽다. 그래서 Chrome 59에서 직접 테스트를 수행했습니다. '삭제'가 약 30 배 느리게 보입니다.

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

다른 작업으로 인한 영향을 최소화하기 위해 한 루프주기에서 여러 개의 '삭제'작업을 의도적으로 수행했습니다.


7

"regex"원래 객체는 항상 프로그램의 다른 부분에서 참조 할 수 있으므로 속성 없이 새 객체를 만드는 것이 좋습니다. 따라서 조작하지 마십시오.

const myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

const { regex, ...newMyObject } = myObject;

console.log(newMyObject);


SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda

Firefox, Chromium 또는 Safari와 같은 최신 브라우저로 사용해보십시오. 그리고 Edge에서도 작동 할 것으로 기대합니다.
ideaboxer

또는 고객이 오래된 브라우저를 지원하도록 강요하는 경우 코드를 레거시 구문으로 변환하는 TypeScript 사용을 고려할 수 있습니다 (+는 정적 유형 안전의 이점을 제공함).
ideaboxer

7

JavaScript에서 속성 제거

이 페이지에는 여러 가지 옵션이 있습니다. 대부분의 옵션이 잘못되었거나 답변이 중복 되었기 때문이 아니라 적절한 기술이 현재 상황과 귀하 및 / 또는 귀하의 작업 목표에 달려 있기 때문입니다. 팀은 성취하려고합니다. 확실하게 질문에 대답하려면 다음을 알아야합니다.

  1. 대상으로하는 ECMAScript 버전
  2. 속성을 제거하려는 객체 유형의 범위와 생략 할 수있는 속성 이름의 유형 (문자열 만? 기호? 임의의 객체에서 매핑 된 약한 참조?) 현재 몇 년 동안 JavaScript에서 속성 포인터 유형이되었습니다. )
  3. 프로그래밍 에토스 / 패턴은 당신과 당신의 팀이 사용합니다. 기능적 접근 방식을 선호하고 팀에서 돌연변이가 발생하거나 와일드 웨스트 돌연변이 체 객체 지향 기술을 사용합니까?
  4. 순수한 JavaScript로 이것을 달성하려고합니까? 아니면 타사 라이브러리를 사용할 수 있습니까?

이 네 가지 질문에 대한 답변이 나오면 목표를 달성하기 위해 JavaScript에서 선택할 수있는 네 가지 범주의 "속성 제거"가 있습니다. 그들은:

안전하지 않은 돌연변이 객체 속성 삭제

이 범주는 원래 참조를 유지 / 계속 사용하려고하고 코드에서 상태 비 저장 기능 원리를 사용하지 않는 경우 객체 리터럴 또는 객체 인스턴스에서 작동합니다. 이 카테고리의 구문 예제 :

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

이 카테고리는 가장 오래되고 가장 간단하며 가장 광범위하게 지원되는 부동산 제거 카테고리입니다. Symbol문자열 외에도 인덱스를 지원 하고 배열하며 첫 번째 릴리스를 제외한 모든 버전의 JavaScript에서 작동합니다. 그러나 일부 프로그래밍 원칙을 위반하고 성능에 영향을 미치는 것은 돌연변이입니다. 또한 엄격 모드에서 구성 할 수없는 특성에 사용될 때 예외가 발생하지 않을 수 있습니다 .

나머지 기반 문자열 속성 생략

이 범주는 비변 이적 접근 방식이 필요하고 기호 키를 고려할 필요가없는 경우 최신 ECMAScript 버전의 일반 객체 또는 배열 인스턴스에서 작동하기위한 것입니다.

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

안전한 돌연변이 객체 속성 삭제

이 범주는 구성 할 수없는 속성에서 발생하는 예외를 방지하면서 원래 참조를 유지 / 계속 사용하려는 경우 객체 리터럴 또는 객체 인스턴스에서 작동합니다.

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

또한, 객체를 제자리에서 변형시키는 것은 상태 비 저장이 아니지만 기능적 특성을 사용하여 Reflect.deleteProperty부분 적용 및 기타 기능으로는 불가능한 기능을 수행 할 수 있습니다delete 명령문으로 .

구문 기반 문자열 속성 생략

이 범주는 비변 이적 접근 방식이 필요하고 기호 키를 고려할 필요가없는 경우 최신 ECMAScript 버전의 일반 객체 또는 배열 인스턴스에서 작동하기위한 것입니다.

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

도서관 기반 부동산 누락

이 범주는 일반적으로 기호 설명 및 하나의 명령문에서 둘 이상의 특성 생략을 포함하여 더 큰 기능적 유연성을 허용합니다.

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"

var keyname = "KeyName"; myObject [키 이름]을 삭제하십시오.
Vikash Chauhan

7

const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)


@CoddWrench 죄송합니다. 그 답변을 보는 데주의를 기울이지 않았습니다. 보고 난 후에 바로 대답합니다 delete myObject.regex;.
xiang

7

rest 연산자와 함께 ES6 파괴를 사용할 수 있습니다.

속성을 사용하여 제거 할 수 있습니다 destructuring을 와 함께 나머지 연산자 . 귀하의 예에서 정규 표현식은 구조화되지 않고 (무시) ​​나머지 속성은 나머지로 반환됩니다.

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

또는 이와 같은 속성을 동적으로 제외 할 수 있습니다.

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }

7

다음을 사용하여 자바 스크립트 객체에서 모든 속성을 제거 할 수 있습니다.

  1. object.property 삭제
  2. 개체 삭제 [ 'property']

예:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

console.log(myObject);

delete myObject.regex;
console.log('=================');
console.log(myObject);
delete myObject['method'];
console.log('=================');
console.log(myObject);


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