Como faço para remover uma propriedade de um objeto JavaScript?

6142

Digamos que eu crie um objeto da seguinte maneira:

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

Qual é a melhor maneira de remover a propriedade regexpara terminar com nova da myObjectseguinte maneira?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
johnstok
fonte
@EscapeNetscape Esta é uma pergunta sobre comportamento, portanto, uma referência mostra a imagem errada. Obviamente, deleteseria a opção mais lenta, pois é uma operação real, e não as outras duas, que são apenas tarefas simples. Mas o cerne da questão é que atribuir a propriedade nullou undefinedna verdade não remover a propriedade do objeto, mas, em vez disso, define essa propriedade para ser igual a um valor constante específico. (As respostas abaixo dão razões pelas quais essa é uma diferença significativa.)
Abion47

Respostas:

8307

Como isso:

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

Demo

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

console.log(myObject);

Para qualquer pessoa interessada em ler mais sobre isso, o usuário do Stack Overflow kangax escreveu uma postagem de blog incrivelmente detalhada sobre a deletedeclaração em seu blog, Entendendo a exclusão . É altamente recomendado.

nickf
fonte
47
Marcado, ele também funciona com "delete myJSONObject ['regex'];" Veja: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok
110
Uma conclusão de uma das observações no link "entendimento de exclusão" acima é que, como você não pode necessariamente excluir uma variável, mas apenas propriedades de objeto, não é possível excluir uma propriedade de objeto "por referência" - var value = obj [ 'suporte']; valor de exclusão // não funciona
Dexygen
27
Então, na verdade, não o exclui? Isso se torna indefinido, mas a chave ainda existe? Estou esquecendo de algo?
Doug Molineux
152
@ Peter não, ele remove. Dado: var x = {a : 'A', b : 'B'};Compare: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */ax.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf 10/08
16
@ChristopherPfohl trabalha para mim. Como eu disse, na verdade é bastante aprofundado, por isso é um pouco difícil de resumir. A resposta básica na resposta acima é suficiente para quase todos os casos, o blog aborda mais alguns casos extremos e os motivos pelos quais esses casos existem.
nickf
953

Objetos em JavaScript podem ser vistos como mapas entre chaves e valores. O deleteoperador é usado para remover essas chaves, mais conhecidas como propriedades do objeto, uma de cada vez.

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

O deleteoperador não libera memória diretamente e difere de simplesmente atribuir o valor de nullou undefineda uma propriedade, pois a própria propriedade é removida do objeto. Observe que se o valor de uma propriedade excluída fosse um tipo de referência (um objeto) e outra parte do seu programa ainda contiver uma referência a esse objeto, é claro que esse objeto não será coletado como lixo até que todas as referências a ele sejam desaparecido.

delete funcionará apenas em propriedades cujo descritor as marca como configuráveis.

Dan
fonte
43
uma propriedade é atribuída a undefined ainda é uma propriedade de um objeto, portanto não será removida pelo GC, a menos que o último parágrafo tenha sido lido errado.
Lance
8
Eu errei ao tocar o tema da GC aqui. Ambos os métodos têm o mesmo resultado para o GC: eles removem o valor vinculado à chave. Se esse valor fosse a última referência a algum outro objeto, esse objeto seria limpo.
Dan
15
uma propriedade é atribuída a undefined ainda é uma propriedade de um objeto, portanto não será removida pelo GC O GC não gerencia nada sobre propriedades. Ele coleta e remove valores. Desde que nada faça referência a um valor (um objeto, string etc.), o GC o remove da memória.
meandre
8
BTW, esse é o problema duplo para verificar se existe uma propriedade no objeto Javascript. Usando no operador é a confiança, mas lento. Verifique se a propriedade não está indefinida "não é a resposta correta", mas é muito mais rápida. verificar
rdllopes
8
Essa resposta ainda é relevante? JSPerf é atualmente para baixo, mas esta referência parece indicar que a diferença de velocidade é uma mera 25%, o que está longe perto dos "~ 100 vezes mais lento" nesta resposta.
Cerbrus
248

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

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

Isso funciona no Firefox e no Internet Explorer, e acho que funciona em todos os outros.

quadrado vermelho
fonte
216

O deleteoperador é usado para remover propriedades dos objetos.

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

Observe que, para matrizes, isso não é o mesmo que remover um elemento . Para remover um elemento de uma matriz, use Array#spliceou Array#pop. Por exemplo:

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

Detalhes

deleteem JavaScript tem uma função diferente da palavra-chave em C e C ++: ela não libera memória diretamente. Em vez disso, seu único objetivo é remover propriedades dos objetos.

Para matrizes, a exclusão de uma propriedade correspondente a um índice cria uma matriz esparsa (isto é, uma matriz com um "furo" nela). A maioria dos navegadores representa esses índices de matriz ausentes como "vazios".

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

Observe que deletenão é realocado array[3]para array[2].

Diferentes funções internas no JavaScript lidam com matrizes esparsas de maneira diferente.

  • for...in pulará o índice vazio completamente.

  • Um forloop tradicional retornará undefinedpara o valor no índice.

  • Qualquer método usando Symbol.iteratorretornará undefinedpara o valor no índice.

  • forEach, mape reducesimplesmente pulará o índice ausente.

Portanto, o deleteoperador não deve ser usado para o caso de uso comum de remover elementos de uma matriz. As matrizes têm métodos dedicados para remover elementos e realocar memória: Array#splice()e Array#pop.

Matriz # emenda (start [, deleteCount [, item1 [, item2 [, ...]]]])

Array#splicemodifica a matriz e retorna todos os índices removidos. deleteCountelementos são removidos do índice starte item1, item2... itemNinseridos na matriz do índice start. Se deleteCountfor omitido, os elementos de startIndex serão removidos no final da matriz.

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

Há também um nome semelhante, mas diferente, função em Array.prototype: Array#slice.

Matriz # fatia ([início [, fim]])

Array#sliceé não destrutivo e retorna uma nova matriz que contém os índices indicados de startpara end. Se não endfor especificado, o padrão será o final da matriz. Se endfor positivo, especifica o índice não inclusivo baseado em zero no qual parar. Se endfor negativo, especifica o índice no qual parar, contando desde o final da matriz (por exemplo, -1 omitirá o índice final). Se end <= start, o resultado é uma matriz vazia.

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]

Matriz # pop

Array#popremove o último elemento de uma matriz e retorna esse elemento. Esta operação altera o comprimento da matriz.

Braden Best
fonte
12
Essa abordagem não modifica o objeto original que ainda pode ser mencionado em outro lugar. Isso pode ou não ser um problema, dependendo de como é usado, mas é algo a ter em mente.
Tamas Czinege 7/11
19
@ B1KMusic Aqui é a maneira de excluir um elemento de uma matriz: tala
wulftone
3
@wulftone não, que divide a matriz e não faz nada para excluir um valor. Eu realmente acho que a melhor maneira de excluir de uma matriz em que valores específicos precisam ser excluídos é usar deletee criar uma função Garbage Collection para limpá-la.
Braden Melhor
5
Eu não vejo splicena sua edição, mas removedeveria serArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-
1
Este artigo está cheio do touro 1. Ele não aborda a questão! 2. É um uso exemplar da linguagem e uma reclamação de que "isso não funciona!" 3. Não culpe o operador de exclusão do JavaScript pelo erro idiossincrático de Crockford de colocar nulo para um índice de matriz vazio. Ele não entende o significado de nulo - ele acha que é um erro. O erro é próprio e isolado - não há nulo no valor excluído de um determinado índice de matriz. Não existe um "buraco" na matriz - esse é um índice vazio. Absolutamente legítimo e esperado.
Bekim Bacaj
195

Pergunta antiga, resposta moderna. Usando a destruição de objetos, um recurso do ECMAScript 6 , é tão simples quanto:

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

Ou com o exemplo de perguntas:

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

Você pode vê-lo em ação no editor de testes da Babel.


Editar:

Para reatribuir à mesma variável, use a let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
Koen.
fonte
6
Talvez porque o objetivo seja remover uma propriedade de um objeto, não criar uma nova sem a propriedade ... embora sua solução seja a minha favorita, pois prefiro o caminho imutável.
Vingt_centimes 01/12/19
8
A pergunta dizia "para terminar com o novo myObject".
Koen.
1
Adicionando Sublinhado para remover uma vontade de maca propriedade seu projeto :) Em vez de tê-lo disponível como regexvocê também pode atribuí-la a qualquer outra variável, por exemplo _, o que é usado em linguagens como Ir para descartar um resultado: const { regex: _, ...newObject } = myObject;.
Koen.
2
@PranayKumar Eu esperava que essa sintaxe funcionasse; const { [key], ...newObject } = myObject;mas não, então não acho possível com a desestruturação.
Koen.
2
Com objetos freeze()d e seal()d, você não pode simplesmente deleteuma propriedade. Portanto, esta é uma excelente alternativa. Embora na maioria dos casos, provavelmente não faça sentido excluir uma propriedade de um objeto congelado / selado de qualquer maneira, considerando que o objetivo principal é garantir certas estruturas de dados, das quais esse padrão estaria prejudicando. Para os casos em que você precisa para não-destrutiva enganar um objeto, mas sem algumas de suas propriedades, este é perfeito
Braden Melhor
119

Sintaxe de propagação (ES6)

Para quem precisa ...

Para concluir a resposta do @Koen neste tópico, caso você queira remover a variável dinâmica usando a sintaxe de propagação, faça o seguinte:

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

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

* fooserá uma nova variável com o valor de a(que é 1).


RESPOSTA ESTENDIDA few
Existem poucas maneiras comuns de remover uma propriedade de um objeto.
Cada um tem seus próprios prós e contras ( verifique esta comparação de desempenho ):

Excluir operador
legível e curto, no entanto, pode não ser a melhor opção se você estiver operando em um grande número de objetos, pois seu desempenho não é otimizado.

delete obj[key];


Reatribuição
Mais que 2X mais rápido quedelete, no entanto, a propriedadenãoéexcluída e pode ser iterada.

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


Operador de propagação
EsseES6operador nos permite retornar um objeto novo em folha, excluindo quaisquer propriedades, sem alterar o objeto existente. A desvantagem é que ele apresenta o pior desempenho dentre os itens acima e não é sugerido o uso quando você precisar remover muitas propriedades ao mesmo tempo.

{ [key]: val, ...rest } = obj;
Lior Elrom
fonte
2
Acho que a sintaxe de propagação / descanso para literais de objetos foi incluída apenas no ES2018 (ES9), não no ES6, embora vários mecanismos JS já o tenham implementado.
trincot
2
@trincot Foi introduzido pela primeira vez em 2014 ( github.com/tc39/proposal-object-rest-spread ) e é um recurso do ES6 (ECMAScript 2015 aka ECMAScript 6th Edition). No entanto, mesmo que eu esteja errado, não acho que isso faça diferença no contexto da resposta.
Lior Elrom
2
O link refere-se ao ES6, onde de fato a sintaxe de propagação foi introduzida para matrizes, mas continua propondo algo semelhante para literais de objetos. Essa segunda parte só foi incorporada no ES9 se não me engano.
Trincot 5/12
98

Outra alternativa é usar a biblioteca Underscore.js .

Note que _.pick()e_.omit() tanto retorno uma cópia do objeto e não modificar diretamente o objeto original. A atribuição do resultado ao objeto original deve fazer o truque (não mostrado).

Referência: link _.pick (objeto, * teclas)

Retorne uma cópia do objeto, filtrada para ter apenas valores para as chaves da lista de permissões (ou matriz de chaves válidas).

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

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

Referência: link _.omit (objeto, * teclas)

Retorne uma cópia do objeto, filtrada para omitir as chaves da lista negra (ou matriz de chaves).

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

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

Para matrizes _.filter()e _.reject()pode ser usado de maneira semelhante.

Thaddeus Albers
fonte
4
Tenha em mente que se as chaves do seu objeto são números, você pode precisar_.omit(collection, key.toString())
Jordan Arseno
Hmmmmm .... Sublinhado é ~ 100x mais lento que o delete obj[prop]que é ~ 100x mais lento que obj[prop] = undefined.
Jack Giffin
52

O termo que você usou no título da sua pergunta Remove a property from a JavaScript objectpode ser interpretado de várias maneiras diferentes. Um é removê-lo para toda a memória e a lista de chaves de objeto ou o outro é apenas para removê-lo do seu objeto. Como foi mencionado em algumas outras respostas, a deletepalavra-chave é a parte principal. Digamos que você tenha seu objeto como:

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

Se você fizer:

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

o resultado seria:

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

Você pode excluir essa chave específica de suas chaves de objeto, como:

delete myJSONObject["regex"];

Então, sua chave de objetos usando Object.keys(myJSONObject)seria:

["ircEvent", "method"]

Mas o ponto é que se você se preocupa com a memória e deseja remover todo o objeto da memória, é recomendável configurá-lo como nulo antes de excluir a chave:

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

O outro ponto importante aqui é ter cuidado com as outras referências ao mesmo objeto. Por exemplo, se você criar uma variável como:

var regex = myJSONObject["regex"];

Ou adicione-o como um novo ponteiro a outro objeto como:

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

Então, mesmo que você o remova do objeto myJSONObject, esse objeto específico não será excluído da memória, pois a regexvariável emyOtherObject["regex"] ainda tem seus valores. Então, como podemos remover o objeto da memória, com certeza?

A resposta seria excluir todas as referências que você possui no seu código, apontar para esse mesmo objeto e também não usar varinstruções para criar novas referências a esse objeto . Este último ponto em relação às vardeclarações é um dos problemas mais cruciais com os quais geralmente nos deparamos, porque usarvar instruções impediria que o objeto criado fosse removido.

O que significa que, nesse caso, você não poderá remover esse objeto porque criou a regexvariável por meio de uma varinstrução e, se o fizer:

delete regex; //False

O resultado seria false, o que significa que sua instrução de exclusão não foi executada conforme o esperado. Mas se você não tivesse criado essa variável antes e tivesse apenas myOtherObject["regex"]a última referência existente, poderia ter feito isso apenas removendo-a como:

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

Em outras palavras, um objeto JavaScript é morto assim que não há mais nenhuma referência no seu código apontada para esse objeto.


Atualização: Graças ao @AgentME:

Definir uma propriedade como nula antes de excluí-la não realiza nada (a menos que o objeto tenha sido selado por Object.seal e a exclusão falhe. Esse não é geralmente o caso, a menos que você tente especificamente).

Para obter mais informações sobre Object.seal: Object.seal ()

Mehran Hatami
fonte
Você está errado - apenas objetos são passados ​​por referência em JavaScript; portanto, se myJSONObject.regexo valor de uma string e você o atribui a outro objeto, o outro objeto possui uma cópia desse valor.
Michał Perłakowski
Você está certo e esta é uma citação: "tenha cuidado com suas outras referências ao mesmo objeto".
Mehran Hatami
43

O ECMAScript 2015 (ou ES6) veio com o objeto Reflect embutido . É possível excluir a propriedade do objeto chamando a função Reflect.deleteProperty () com o objeto de destino e a chave de propriedade como parâmetros:

Reflect.deleteProperty(myJSONObject, 'regex');

que é equivalente a:

delete myJSONObject['regex'];

Mas se a propriedade do objeto não for configurável, ela não poderá ser excluída nem com a função deleteProperty nem com o operador delete:

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

Object.freeze () torna todas as propriedades do objeto não configuráveis ​​(além de outras coisas). deletePropertyA função (assim como o operador delete ) retorna falsequando tenta excluir qualquer uma de suas propriedades. Se a propriedade for configurável, ela retornará true, mesmo que a propriedade não exista.

A diferença entre deletee deletePropertyé ao usar o modo estrito:

"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
madox2
fonte
1
@ Gothdo tem mais benefícios, especialmente quando você precisa fazer algumas coisas funcionais. Por exemplo, você pode atribuir a função de variáveis, passar como um argumento ou uso apply, call, bindfunções ...
madox2
41

Suponha que você tenha um objeto parecido com este:

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

Excluindo uma propriedade de objeto

Se você deseja usar toda a staffmatriz, a maneira correta de fazer isso seria:

delete Hogwarts.staff;

Como alternativa, você também pode fazer isso:

delete Hogwarts['staff'];

Da mesma forma, a remoção de toda a matriz de alunos seria feita chamando delete Hogwarts.students;ou delete Hogwarts['students'];.

Excluindo um índice de matriz

Agora, se você deseja remover um único membro da equipe ou aluno, o procedimento é um pouco diferente, porque as duas propriedades são elas mesmas.

Se você conhece o índice do seu membro da equipe, você pode simplesmente fazer o seguinte:

Hogwarts.staff.splice(3, 1);

Se você não conhece o índice, também precisará fazer uma pesquisa no índice:

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

Nota

Embora você possa usar tecnicamente deletepara uma matriz, usá-la resultaria em resultados incorretos ao chamar, por exemplo, Hogwarts.staff.lengthmais tarde. Em outras palavras, deleteremoveria o elemento, mas não atualizaria o valor da lengthpropriedade. O uso deletetambém atrapalhava sua indexação.

Portanto, ao excluir valores de um objeto, sempre considere primeiro se você está lidando com propriedades do objeto ou se está lidando com valores de matriz e escolha a estratégia apropriada com base nisso.

Se você quiser experimentar isso, pode usar este Fiddle como ponto de partida.

John Slegers
fonte
Eu acho que você deve sempre usar spliceem uma matriz em vez de delete.
Joel Trauger 22/09/16
@JoelTrauger: Isso é o que estou dizendo ;-)
John Slegers
Sim. Meu comentário é que isso deletenem deveria ser uma coisa. É spliceisso que o OP estava procurando.
Joel Trauger
1
@ JoelTrauger: Como tentei explicar, deletedeve ser usado para propriedades de objetos e spliceelementos de matriz.
John Slegers
A emenda é realmente lenta. Embora deva ser usado em vez de deletematrizes, seria mais sensato não criar código centralizado em torno dele.
Jack Giffin
39

Usando o ES6:

(Operador de Reestruturação + Spread)

const myObject = {
    regex: "^http://.*",
    b: 2,
    c: 3
};
const { regex, ...noRegex } = myObject;
console.log(noRegex); // => { b: 2, c: 3 }
Srinivas
fonte
Eu não acho que esse seja um recurso do ES6, mas que foi incluído apenas no ES9.
precisa saber é
Então, na verdade você não está usando ES6, como você escreve, mas ES9 ... ;-)
trincot
2
Isso não está removendo uma propriedade de um objeto, mas criando um novo objeto sem essa propriedade.
precisa
32

Eu pessoalmente uso Underscore.js ou Lodash para manipulação de objetos e matrizes:

myObject = _.omit(myObject, 'regex');
emil
fonte
31

O operador de exclusão é a melhor maneira de fazer isso.

Um exemplo ao vivo para mostrar:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
Tarun Nagpal
fonte
Pode-se notar que, embora o uso do deleteoperador seja saudável em relação à coleta de lixo , ele pode ser inesperadamente lento , em grande parte pelo mesmo motivo.
John Weisz
29

Para clonar objeto sem propriedade:

Por exemplo:

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

E precisamos excluir 'a'.

1.Com chave de suporte explícita:

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

2. Com chave de suporte variável:

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

Função da seta 3.Cool:

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

object = removePropery('a', object);

4. Para várias propriedades

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

Uso

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

Ou

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
YairTawil
fonte
1
Função de seta lisa!
JSilv
27

Usar o método delete é a melhor maneira de fazer isso, conforme a descrição do MDN, o operador delete remove uma propriedade de um objeto. Então você pode simplesmente escrever:

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

O operador delete remove uma determinada propriedade de um objeto. Na exclusão bem-sucedida, ele retornará true, caso contrário, false será retornado. No entanto, é importante considerar os seguintes cenários:

  • Se a propriedade que você está tentando excluir não existir, a exclusão não terá nenhum efeito e retornará true

  • Se uma propriedade com o mesmo nome existir na cadeia de protótipos do objeto, após a exclusão, o objeto usará a propriedade da cadeia de protótipos (em outras palavras, a exclusão terá efeito apenas nas próprias propriedades).

  • Qualquer propriedade declarada com var não pode ser excluída do escopo global ou do escopo de uma função.

  • Como tal, delete não pode excluir nenhuma função no escopo global (seja parte de uma definição de função ou de uma função (expressão).

  • Funções que fazem parte de um objeto (além do
    escopo global) podem ser excluídas com exclusão.

  • Qualquer propriedade declarada com let ou const não pode ser excluída do escopo dentro do qual foram definidas. Propriedades não configuráveis ​​não podem ser removidas. Isso inclui propriedades de objetos internos como Math, Array, Object e propriedades criadas como não configuráveis ​​com métodos como Object.defineProperty ().

O fragmento a seguir fornece outro exemplo simples:

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

Para obter mais informações e ver mais exemplos, visite o link abaixo:

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

Alireza
fonte
22

Outra solução, usando 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);

No entanto, ele irá transformar o objeto original. Se você deseja criar um novo objeto sem a chave especificada, apenas atribua a função de redução a uma nova variável, por exemplo:

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

usuário gentil
fonte
21

Este post é muito antigo e eu acho muito útil, então decidi compartilhar a função não configurada que escrevi, caso alguém o veja e pense por que não é tão simples quanto na função não configurada PHP.

O motivo para escrever essa nova unsetfunção é manter o índice de todas as outras variáveis ​​neste hash_map. Veja o exemplo a seguir e veja como o índice de "test2" não foi alterado após remover um valor do hash_map.

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"}
talsibony
fonte
20

Há muitas boas respostas aqui, mas quero enfatizar que, ao usar delete para remover uma propriedade em JavaScript, geralmente é aconselhável verificar primeiro se essa propriedade existe para evitar erros.

Por exemplo

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

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

Devido à natureza dinâmica do JavaScript, geralmente há casos em que você simplesmente não sabe se a propriedade existe ou não. Verificar se obj existe antes do && também garante que você não gere um erro devido à chamada da função hasOwnProperty () em um objeto indefinido.

Desculpe se isso não foi adicionado ao seu caso de uso específico, mas acredito que este seja um bom design para se adaptar ao gerenciar objetos e suas propriedades.

Willem
fonte
2
excluir foo.bar funciona mesmo que a barra não exista, então seu teste é um pouco demais, IMHO.
PhiLho
@ PhiLho que depende de onde você está executando o JavaScript. No Node.js, acredito que isso causa uma falha no servidor.
Willem
2
delete foo.bar;somente lança uma exceção se foo for falso ou se você estiver no modo estrito e foo for um objeto com uma propriedade de barra não configurável.
Macil 02/06/2015
Não me lembro do problema exato que tive com isso, mas acho que o problema pode aparecer quando o foo em si não existe e você tenta excluir sua propriedade.
Willem
Sim, você deve testar se o foo existe, caso contrário, o foo.bar lançará uma exceção, mas você não precisará verificar a existência da barra antes de excluí-la. Essa é a parte "demais" do meu comentário. :-)
PhiLho 3/15
16

Usando ramda # dissoc, você obterá um novo objeto sem o atributo regex:

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

Você também pode usar outras funções para obter o mesmo efeito - omitir, escolher, ...

Amio.io
fonte
15

Tente o seguinte método. Atribua o Objectvalor da propriedade a undefined. Então stringifyo objeto e parse.

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

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

console.log(myObject);

Mohammed Safeer
fonte
1
TambémJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy 25/09/16
12

Se você deseja excluir uma propriedade profundamente aninhada no objeto, pode usar a seguinte função recursiva com caminho para a propriedade como o segundo argumento:

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

Exemplo:

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

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

//Prints {level1: {level2: {}}}
ayushgp
fonte
Essa função funciona como um encanto, mas por que precisamos retornar verdadeiro e retornar falso? Minha versão do código: codepen.io/anon/pen/rwbppY . Minha versão falhará em qualquer caso?
theusual
@ witty2017 não vai falhar. O local em que usei a função também precisava verificar se a propriedade já existe ou não. se a propriedade não existir, ela retornará false. Se encontrar a propriedade e excluí-la, retornará true.
ayushgp
8

Você pode simplesmente excluir qualquer propriedade de um objeto usando a deletepalavra - chave

Por exemplo:

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

Para remover qualquer propriedade, digamos key1, use a deletepalavra - chave assim:

delete obj.key1

Ou você também pode usar a notação de matriz:

delete obj[key1]

Ref: MDN .

Kalpesh Patel
fonte
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"];
        }
    }
);

xgqfrms-gildata
fonte
7

A afirmação de Dan de que 'excluir' é muito lenta e a referência que ele postou foi duvidosa. Portanto, eu mesmo realizei o teste no Chrome 59. Parece que 'delete' é cerca de 30 vezes mais lento:

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

Observe que, propositadamente, realizei mais de uma operação de 'exclusão' em um ciclo de loop para minimizar o efeito causado pelas outras operações.

Chong Lip Phang
fonte
7

Considere criar um novo objeto sem a "regex"propriedade porque o objeto original sempre pode ser referenciado por outras partes do seu programa. Portanto, você deve evitar manipulá-lo.

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

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

console.log(newMyObject);

ideaboxer
fonte
SyntaxError: Unexpected token '...'. Expected a property name.?
21418 Krzysztof Przygoda #
Experimente com um navegador moderno, como Firefox, Chromium ou Safari. E espero que funcione com o Edge também.
Ideaboxer
Como alternativa, se seus clientes o forçarem a oferecer suporte a navegadores desatualizados, considere usar o TypeScript que transpila seu código para a sintaxe herdada (+ oferece o benefício da segurança de tipo estático).
Ideaboxer
7

Remoção de propriedade em JavaScript

Existem muitas opções diferentes apresentadas nesta página, não porque a maioria das opções esteja errada - ou porque as respostas são duplicadas - mas porque a técnica apropriada depende da situação em que você está e dos objetivos das tarefas que você e / ou você equipe está tentando cumprir. Para responder sua pergunta inequivocamente, é preciso saber:

  1. A versão do ECMAScript que você está segmentando
  2. O intervalo de tipos de objetos nos quais você deseja remover propriedades e o tipo de nomes de propriedades que você precisa para poder omitir (somente Strings? Símbolos? Referências fracas mapeadas a partir de objetos arbitrários? Todos esses são tipos de indicadores de propriedade em JavaScript há anos. )
  3. O ethos / padrões de programação que você e sua equipe usam. Você é a favor de abordagens funcionais e a mutação é verbal em sua equipe, ou você utiliza técnicas orientadas a objetos mutantes do oeste selvagem?
  4. Você está procurando conseguir isso em JavaScript puro ou deseja ou pode usar uma biblioteca de terceiros?

Depois que essas quatro perguntas forem respondidas, existem basicamente quatro categorias de "remoção de propriedade" no JavaScript para escolher, a fim de atingir seus objetivos. Eles são:

Exclusão de propriedade de objeto mutativa, insegura

Essa categoria é para operar em literais ou instâncias de objeto quando você deseja manter / continuar usando a referência original e não está usando princípios funcionais sem estado no seu código. Um exemplo de sintaxe nesta categoria:

'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

Esta categoria é a categoria de remoção de propriedade mais antiga, direta e amplamente suportada. Ele suporta Symbol& índices de matriz, além de strings e funciona em todas as versões do JavaScript, exceto na primeira versão. No entanto, é mutativo que viola alguns princípios de programação e tem implicações no desempenho. Também pode resultar em exceções não capturadas quando usado em propriedades não configuráveis ​​no modo estrito .

Omissão de propriedade de sequência baseada em descanso

Essa categoria é para operar em instâncias simples de objeto ou matriz em tipos mais recentes de ECMAScript quando uma abordagem não-mutativa é desejada e você não precisa considerar as chaves Symbol:

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 :(

Exclusão mutável de propriedade de objeto, segura

Esta categoria é para operar em literais de objetos ou instâncias de objetos quando você deseja manter / continuar a usar a referência original enquanto se protege contra exceções lançadas em propriedades não configuráveis:

'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

Além disso, embora a mutação de objetos no local não seja apátrida, você pode usar a natureza funcional de Reflect.deletePropertyfazer aplicação parcial e outras técnicas funcionais que não são possíveis com deleteinstruções.

Omissão de propriedade de cadeia de caracteres baseada em sintaxe

Essa categoria é para operar em instâncias simples de objeto ou matriz em tipos mais recentes de ECMAScript quando uma abordagem não-mutativa é desejada e você não precisa considerar as chaves Symbol:

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 :(

Omissão de propriedade baseada em biblioteca

Essa categoria geralmente permite maior flexibilidade funcional, incluindo contabilização de símbolos e omissão de mais de uma propriedade em uma instrução:

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"
james_womack
fonte
var keyname = "KeyName"; delete myObject [keyname];
Vikash Chauhan
7

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

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

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

xiang
fonte
@ CododWrench Desculpe, eu não prestei atenção ao ver essa resposta. Eu respondo imediatamente depois de ver delete myObject.regex;.
xiang
7

Você pode usar a desestruturação do ES6 com o operador rest.

As propriedades podem ser removidas usando a desestruturação em combinação com o operador restante . No seu exemplo, a regex é destruída (ignorada) e o restante das propriedades é retornado como restante.

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

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

Ou você pode excluir dinamicamente propriedades como esta,

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://.*" }
Bhargav Patel
fonte
7

Podemos remover qualquer propriedade de um objeto javascript usando o seguinte:

  1. excluir object.property
  2. excluir objeto ['propriedade']

exemplo:

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

Ravi Ranjan
fonte
6

Tente isto

delete myObject['key'];
codemirror
fonte