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

Digamos que eu crie um object da seguinte maneira:

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

Qual é a melhor maneira de remover a regex propriedade para terminar com o novo myObject seguinte maneira?

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

Como isso:

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

Demonstração

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

A delete operador é inesperadamente lenta!

Olhe para o benchmark .

Excluir é a única maneira verdadeira de remover as propriedades do object sem quaisquer sobras, mas ele funciona ~ 100 vezes mais lentamente , comparado ao seu object[key] = undefined configuração “alternativo” object[key] = undefined .

Essa alternativa não é a resposta correta para essa pergunta! Mas, se você usá-lo com cuidado, você pode acelerar dramaticamente alguns algoritmos. Se você estiver usando delete in loops e tiver problemas com o desempenho, leia a explicação detalhada.

Quando alguém deve usar delete e quando set value para undefined ?

Um object pode ser visto como um conjunto de pares de valores-chave. O que eu chamo de ‘valor’ é uma primitiva ou uma referência a outro object, conectado a essa ‘chave’.

Use delete , quando você estiver passando o object de resultado para o código no qual você não tem controle (ou quando você não tem certeza sobre sua equipe ou sobre você).

Exclui a chave do hashmap .

  var obj = { field: 1 }; delete obj.field; 

Use a configuração como undefined quando você se preocupa com o desempenho. Isso pode dar um grande impulso ao seu código.

A chave permanece em seu lugar no hashmap , apenas o valor é substituído por undefined . Entenda que o loop for..in ainda irá iterar sobre essa chave.

  var obj = { field: 1 }; obj.field = undefined; 

Usando este método, nem todas as formas de determinar a existência da propriedade funcionarão conforme o esperado.

No entanto, este código:

object.field === undefined

irá se comportar de maneira equivalente para ambos os methods.

Testes

Resumindo, as diferenças são todas sobre formas de determinar a existência da propriedade e sobre o loop for..in .

  console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."'); console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *'); console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *'); console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *'); console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *'); console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!'); //Object.keys().indexOf() is an overkill that runs much slower :) var counter = 0, key; for (key in obj) { counter++; } console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *'); 

Cuidado com os vazamentos de memory!

Enquanto usar obj[prop] = undefined é mais rápido que fazer delete obj[prop] , outra consideração importante é que obj[prop] = undefined pode nem sempre ser apropriado. delete obj[prop] remove prop do obj e apaga-o da memory, enquanto obj[prop] = undefined simplesmente define o valor de prop para undefined que o deixa imóvel na memory. Portanto, em circunstâncias em que há muitas chaves sendo criadas e excluídas, o uso de obj[prop] = undefined pode forçar a reconciliação de memory cara (causando o congelamento da página) e, potencialmente, um erro de falta de memory. Examine o código a seguir.

 "use strict"; var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[]; for (i = 0; i !== numberOfNodes; i++) { nodeRecords[i] = []; current = theNodeList[i] = document.createElement("div"); current.textContent = i; document.body.appendChild( current ); } var lastTime = -1; requestAnimationFrame(function recordUpdates(){ var currentTime = Math.round( performance.now()*1000 ) for (i = 0; i !== numberOfNodes; i++) { if (lastTime !== -1) { // the previously collected data is no longer in use /*************************************************/ /****/ nodeRecords[i][lastTime] = undefined; /****/ /*************************************************/ } nodeRecords[i][currentTime] = theNodeList[i].outerHTML; } lastTime = currentTime; requestAnimationFrame( recordUpdates ); }); 

No código acima, simplesmente fazendo nodeRecords[i][lastTime] = undefined; causará um memory leaks massivo porque cada quadro de animação. Cada quadro, todos os 65536 elementos DOM ocuparão outros 65536 slots individuais, mas os 65536 slots anteriores serão definidos apenas como undefined, o que os deixará na memory. Vá em frente, tente executar o código acima no console e veja por si mesmo. Depois de forçar um erro de falta de memory, tente executá-lo novamente, exceto com a seguinte versão do código que usa o operador delete .

 "use strict"; var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[]; for (i = 0; i !== numberOfNodes; i++) { nodeRecords[i] = []; current = theNodeList[i] = document.createElement("div"); current.textContent = i; document.body.appendChild( current ); } var lastTime = -1; requestAnimationFrame(function recordUpdates(){ var currentTime = Math.round( performance.now()*1000 ) for (i = 0; i !== numberOfNodes; i++) { if (lastTime !== -1) { // the previously collected data is no longer in use /********************************************/ /****/ delete nodeRecords[i][lastTime]; /****/ /********************************************/ } nodeRecords[i][currentTime] = theNodeList[i].outerHTML; } lastTime = currentTime; requestAnimationFrame( recordUpdates ); }); 

Como visto no trecho de código acima, há alguns casos de uso apropriados raros para o operador delete . No entanto, não se preocupe muito com esse problema. Isso só se tornará um problema com objects de longa vida que recebem novas chaves constantemente adicionadas a eles. Em qualquer outro caso (que é quase todo caso na programação do mundo real), é mais apropriado usar obj[prop] = undefined . O principal objective desta seção é apenas chamar a sua atenção para que, na rara chance de que isso se torne um problema em seu código, você possa entender mais facilmente o problema e, portanto, não ter que perder horas dissecando seu código para localizar e entender esse problema.

Nem sempre defina para undefined

Um aspecto do Javascript que é importante considerar é o polymorphism. O polymorphism é quando se atribuem os mesmos tipos diferentes de variables ​​/ slots em um object, como visto abaixo.

 var foo = "str"; foo = 100; // variable foo is now labeled polymorphic by the browser var bar = ["Some", "example"]; bar[2] = "text"; // bar is a monomorphic array here because all its entries have the // same type: string primitive bar[1] = undefined; // bar is now a polymorphic array 

No entanto, existem dois problemas principais não corrigíveis com matrizes polimórficas:

  1. Eles são lentos e ineficientes de memory. Ao acessar um índice específico, em vez de apenas obter o tipo global para a matriz, o navegador precisa obter o tipo em uma base por índice, em que cada índice armazena os metadados adicionais de seu tipo.
  2. Uma vez polimórfico, sempre polimórfico. Quando uma matriz é feita polimórfica, o polymorphism não pode ser desfeito nos navegadores Webkit. Portanto, mesmo se você restaurar um array polimórfico para não ser polimórfico, ele ainda será armazenado pelo navegador como um array polimórfico.

Pode-se comparar o polymorphism a um vício em drogas. À primeira vista, parece incrivelmente lucrativo: código bonito e fofo. Então, o codificador introduz sua matriz à droga do polymorphism. Instantaneamente, o arranjo polimórfico se torna menos eficiente, e nunca pode se tornar tão eficiente quanto antes, já que é drogado. Para correlacionar tal circunstância com a vida real, alguém com cocaína pode nem mesmo ser capaz de operar uma maçaneta de porta simples, e muito menos ser capaz de calcular dígitos de IP. Da mesma forma, uma matriz na droga do polymorphism não pode ser tão eficiente quanto uma matriz monomórfica.

Mas, como uma analogia de viagem de drogas se relaciona com a operação de delete ? A resposta é inerente à última linha de código no snippet acima. Assim deixe ser reexaminado, desta vez com uma torção.

 var bar = ["Some", "example"]; bar[2] = "text"; // bar is not a polymorphic array here because all its entries have the // same type: string primitive bar[1] = ""; // bar is still a monomorphic array bar[1] = undefined; // bar is now a polymorphic array 

Observar. bar[1] = "" não coage o polymorphism enquanto bar[1] = undefined faz. Portanto, deve-se sempre, sempre que possível, usar o tipo correspondente para seus objects, de modo a não causar acidentalmente polymorphism. Uma dessas pessoas pode usar a seguinte lista como uma referência geral para fazê-las funcionar. No entanto, por favor, não use explicitamente as idéias abaixo. Em vez disso, use o que funciona bem para o seu código.

  • Ao usar uma matriz / variável digitada na primitiva booleana, use false ou undefined como o valor vazio. Embora evitar polymorphism desnecessário seja bom, rewrite todo o código para proibi-lo explicitamente provavelmente resultará em uma diminuição no desempenho. Use julgamento comum!
  • Ao usar uma matriz / variável digitada na primitiva do número, use 0 como o valor vazio. Observe que, internamente, existem dois tipos de números: inteiros rápidos (2147483647 a -2147483648 inclusive) e duplos de ponto flutuante lentos (qualquer coisa além disso, incluindo NaN e Infinity ). Quando um inteiro é rebaixado para um duplo, ele não pode ser promovido de volta para um inteiro.
  • Ao usar uma matriz / variável digitada na primitiva de cadeia, use "" como o valor vazio.
  • Ao usar um símbolo, espere, por que você está usando um símbolo?!?! Os símbolos são ruins para o desempenho. Tudo programado para usar símbolos pode ser reprogramado para não usar símbolos, resultando em um código mais rápido sem símbolos. Os símbolos são realmente apenas super-eficientes meta-açúcares.
  • Ao usar qualquer outra coisa, use null .

No entanto, esteja atento! De repente, não comece a fazer isso com todo o seu código preexistente agora, pois isso provavelmente quebraria esse código preexistente e / ou introduziria bugs estranhos. Em vez disso, uma prática tão eficiente precisa ser implementada desde o início e, ao converter código preexistente, é recomendável que você duplique, triplique, quadruplique e verifique todas as linhas relacionadas a isso, pois tentar atualizar o código antigo para essa nova prática pode ser arriscado como recompensador.

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

Atualização 2018-07-21: Por um longo tempo, eu me senti envergonhado com esta resposta, então acho que é hora de eu tocar um pouco. Apenas um pequeno comentário, esclarecimento e formatação para ajudar a agilizar a leitura das partes desnecessariamente longas e complicadas dessa resposta.


A VERSÃO CURTA

A resposta real à pergunta

Como outros já disseram, você pode usar delete .

 obj // {"foo": "bar"} delete obj["foo"] obj // {} obj["foo"] // undefined 

Equivalente de matriz

Não delete de uma matriz. Use Array.prototype.splice vez disso.

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

A VERSÃO LONGA

JavaScript é uma linguagem OOP, então tudo é um object, incluindo matrizes . Assim, sinto que é necessário apontar uma advertência específica.

Em arrays, ao contrário de objects antigos simples, o uso de delete deixa para trás o lixo na forma de null , criando um “buraco” na matriz.

 var array = [1, 2, 3, 4]; delete array[2]; /* Expected result --> [1, 2, 4] * Actual result --> [1, 2, null, 4] */ 

Como você pode ver, delete nem sempre funciona como se poderia esperar. O valor é sobrescrito, mas a memory não é realocada. Isto é, array[4] não é realocado para array[3] . O que está em contraste com Array.prototype.unshift , que insere um elemento no começo da matriz e desloca tudo para cima ( array[0] se torna array[1] , etc.)

Honestamente, além de definir como null ao invés de undefined que é legitimamente estranho – esse comportamento não deveria ser surpreendente, já que delete é um operador unário, como typeof , que é hard-boiled na linguagem e não deveria se importar sobre o tipo de object que está sendo usado, enquanto Array é uma subclass de Object com methods projetados especificamente para trabalhar com arrays. Portanto, não há uma boa razão para o delete ter um caso especial preparado para re-mudar o array, pois isso só retardaria as coisas com um trabalho desnecessário. Em retrospecto, minhas expectativas não eram realistas.

Claro, isso me surpreendeu. Porque eu escrevi isso para justificar minha cruzada contra o “lixo nulo”:

Ignorando os perigos e problemas inerentes ao null e o espaço desperdiçado, isso pode ser problemático se o array precisar ser preciso.

O que é uma justificativa terrível para se livrar do null s – null é perigoso apenas se usado de forma inadequada, e não tem nada a ver com “precisão”. A verdadeira razão pela qual você não deve delete de uma matriz é porque deixar estruturas de dados cheias de lixo e bagunçadas é desleixado e propenso a erros.

O que se segue é um cenário artificial que fica bastante longo, então você pode pular para a seção, A Solução , se quiser. A única razão pela qual eu deixo essa seção é porque eu acho que algumas pessoas provavelmente acham engraçado, e eu não quero ser “aquele cara” que posta uma resposta “engraçada” e então apaga todo o “engraçado” dela mais tarde .

… É estúpido, eu sei.

O cenário de PDP-11 inventado e prolixo

Por exemplo, digamos que você esteja criando um webapp que usa serialização JSON para armazenar um array usado para ‘guias’ em uma string (nesse caso, localStorage ). Digamos também que o código usa os índices numéricos dos membros da matriz para “título” ao desenhar na canvas. Por que você está fazendo isso em vez de apenas armazenar o “título” também? Porque … razões .

Ok, digamos apenas que você está tentando economizar memory a pedido deste usuário que opera um minicomputador PDP-11 da década de 1960 rodando o UNIX, e escreveu seu próprio minicomputador baseado em Elinks, compatível com JavaScript, compatível com impressoras de linha. navegador porque o X11 está fora de questão .

Deixando de lado o cenário de caso de borda cada vez mais estúpido, usar a delete na matriz mostrará null poluindo a matriz e provavelmente causando bugs no aplicativo mais tarde. E se você verificar por null , ele irá pular os números, resultando nas abas sendo renderizadas como [1] [2] [4] [5] ...

 if (array[index] == null) continue; else title = (index + 1).toString(); /* 0 -> "1" * 1 -> "2" * 2 -> (nothing) * 3 -> "4" */ 

Sim, definitivamente não é o que você queria.

Agora, você poderia manter um segundo iterador, como j , para incrementar somente quando valores válidos forem lidos da matriz. Mas isso não resolveria exatamente o problema null , e você ainda tem que agradar ao usuário do troll PDP-11. Infelizmente, o computador dele não tem memory suficiente para armazenar o último inteiro (não pergunte como ele consegue lidar com uma matriz de largura variável …) .

Então, ele envia um e-mail com raiva:

 Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found: >"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]" After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES! >var i = index; >var j = 1; Grr, I am angry now. -Troll Davidson 

Até agora, você está no final da sua sagacidade. Esse cara tem reclamado sem parar sobre o seu aplicativo, e você quer dizer a ele para calar a boca e ir buscar um computador melhor.

A solução: Array.prototype.splice

Felizmente, as matrizes têm um método especializado para excluir índices e realocar memory: Array.prototype.splice() . Você poderia escrever algo assim:

 Array.prototype.remove = function(index){ this.splice(index,1); } ... array = [1, 2, 3, 4]; array.remove(2); // Result -> [1, 2, 4] 

E assim, você está satisfeito com o Sr. PDP-11. Viva! (Eu ainda diria a ele, embora …)

Array.prototype.splice vs Array.prototype.slice

Eu sinto que é importante ressaltar a diferença entre essas duas funções de nome similar, pois ambas são muito úteis.

Array.prototype.splice (start, n)

.splice() a matriz e retorna os índices removidos. A matriz é dividida a partir do índice, start e n elementos são cortados. Se n não for especificado, todo o array após o start será cortado ( n = array.length - start ).

 let a = [5,4,3,2,1]; let chunk = a.splice(2,2); // a [5,4,3,2,1] // start 0 1 2 - - // n - - 1 2 - chunk; // [3,2] a; // [5,4,1] 

Array.prototype.slice (início, fim)

.slice() não é destrutivo e retorna uma nova matriz contendo os índices indicados do start ao end . Se end for especificado, o comportamento será o mesmo que .splice() ( end = array.length ). O comportamento é um pouco complicado, pois, por algum motivo, end índices de 1 em vez de 0. Não sei por que isso acontece, mas é assim. Além disso, se end < = start , o resultado será uma matriz vazia.

 let a = [5,4,3,2,1]; let chunks = [ a.slice(2,0), a.slice(2,2), a.slice(2,3), a.slice(2,5) ]; // a [5,4,3,2,1] // start 0 1 2 - - // end, for... - - - - - // chunks[0] 0 - - - - - // chunks[1] 1 2 - - - // chunks[2] 1 2 3 - - // chunks[3] 1 2 3 4 5 chunks; // [ [], [], [3], [3,2,1] ] a; // [5,4,3,2,1] 

Isso na verdade não é o que está acontecendo, mas é mais fácil pensar dessa maneira. De acordo com o MDN, eis o que está realmente acontecendo:

 // a [5,4,3,2,1] // start 0 1 2 - - - // end, for... - - - - - - // chunks[0] 0 - - - - - // chunks[1] 0 1 2 - - - // chunks[2] 0 1(2)3 - - // chunks[3] 0 1(2 3 4)5 

O índice especificado por end é simplesmente excluído da fatia. Os índices entre parênteses indicam o que é fatiado. De qualquer forma, o comportamento não é intuitivo e está fadado a causar a sua quota de erros off-by-one, então você pode achar útil fazer uma function wrapper para emular mais de perto o comportamento de .splice() :

 function ez_slice(array, start = 0, n = null){ if(!Array.isArray(array) || !is_number(start)) return null; if(is_number(n)) return array.slice(start, start + n); if(n === null) return array.slice(start); return null; } ez_slice([5,4,3,2,1], 2, 1) // [3] ez_slice([5,4,3,2,1], 2) // [3,2,1] /* Fun fact: isNaN is unreliable. * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN) * [NaN, {}, undefined, "Hi"] * * What we want is... * * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan) * [NaN] */ function is_nan(num){ return typeof num === "number" && num !== num; } function is_number(num){ return !is_nan(num) && typeof num === "number" && isFinite(num); } 

Observe que a function de invólucro é projetada para ser muito rigorosa sobre os tipos e retornará null se alguma coisa estiver desativada. Isso inclui colocar uma string como "3" . Cabe ao programador ser diligente com seus tipos. Isso é para incentivar boas práticas de programação.

Atualização sobre is_array()

Isto é em relação a este fragment (agora removido):

 function is_array(array){ return array !== null && typeof array === "object" && typeof array.length !== "undefined" && array.__proto__ === Array.prototype; } 

Então, na verdade, existe uma maneira Array.isArray() de dizer se um array é verdadeiramente um array, e isso é Array.isArray() , introduzido no ECMAScript 5 (dezembro de 2009). Eu encontrei isso enquanto procurava para ver se havia uma pergunta perguntando sobre as matrizes de objects, para ver se havia uma solução melhor do que a minha, ou para adicionar a minha se não houvesse nenhuma. Portanto, se você estiver usando uma versão do JavaScript anterior ao ECMA 5, haverá o seu polyfill. No entanto, é altamente recomendável não usar minha function is_array() , pois continuar is_array() suporte a versões antigas de JavaScript significa continuar a oferecer suporte aos navegadores antigos que os implementam, o que significa incentivar o uso de software inseguro e colocar os usuários em risco de malware. Então, por favor, use Array.isArray() . Use let e const . Use os novos resources adicionados ao idioma. Não use prefixos de fornecedores. Exclua aquela porcaria do Polyfill do IE do seu site. Exclua esse XHTML < !CDATA[[... porcaria, também - mudamos para o HTML5 em 2014. Quanto mais cedo todos desistirem do suporte para esses navegadores antigos / esotéricos, mais cedo os fornecedores de navegadores seguirão o padrão da Web e adotarão o nova tecnologia, e quanto mais cedo pudermos passar para uma web mais segura.

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

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

Ou com a amostra 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 teste do Babel.


Editar:

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

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

Outra alternativa é usar a biblioteca Underscore.js .

Observe que _.pick() e _.omit() retornam uma cópia do object e não modificam diretamente o object original. Atribuir o resultado ao object original deve fazer o truque (não mostrado).

Referência: link _.pick (object, * keys)

Retorna uma cópia do object, filtrada para ter apenas valores para as chaves na lista de permissions (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 (object, * chaves)

Retorna uma cópia do object, filtrada para omitir as chaves na 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() podem ser usados ​​de maneira semelhante.

O termo que você usou no título da pergunta Remove a property from a JavaScript object , pode ser interpretado de maneiras diferentes. O único é removê-lo por toda a memory e a lista de chaves de objects ou o outro é apenas para removê-lo do seu object. Como foi mencionado em algumas outras respostas, a palavra-chave delete é a parte principal. Digamos que você tenha seu object 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 object como:

 delete myJSONObject["regex"]; 

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

 ["ircEvent", "method"] 

Mas o ponto é que, se você se importa com a memory e deseja que todo o object seja removido da memory, é recomendável defini-lo como nulo antes de excluir a chave:

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

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

 var regex = myJSONObject["regex"]; 

Ou adicione-o como um novo ponteiro para outro object como:

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

Então, mesmo se você removê-lo do seu object myJSONObject , esse object específico não será excluído da memory, já que a variável regex e myOtherObject["regex"] ainda terão seus valores. Então, como poderíamos remover o object da memory com certeza?

A resposta seria excluir todas as referências que você tem em seu código, apontadas para esse mesmo object e também não usar instruções var para criar novas referências a esse object . Este último ponto referente às instruções var , é um dos problemas mais cruciais que normalmente enfrentamos, porque o uso de instruções var impediria que o object criado fosse removido.

O que significa que, nesse caso, você não poderá remover esse object porque criou a variável regex por meio de uma instrução var e, se fizer isso:

 delete regex; //False 

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

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

Em outras palavras, um object JavaScript é eliminado assim que não houver mais nenhuma referência em seu código apontada para esse object.


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

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

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

Suponha que você tenha um object assim:

 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 object

Se você quiser usar toda a matriz da staff , a maneira correta de fazer isso seria fazer isso:

 delete Hogwarts.staff; 

Alternatively, you could also do this:

 delete Hogwarts['staff']; 

Similarly, removing the entire students array would be done by calling delete Hogwarts.students; or delete Hogwarts['students']; .

Deleting an array index

Now, if you want to remove a single staff member or student, the procedure is a bit different, because both properties are arrays themselves.

If you know the index of your staff member, you could simply do this:

 Hogwarts.staff.splice(3, 1); 

If you do not know the index, you’ll also have to do an index search:

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

Nota

While you technically can use delete for an array, using it would result in getting incorrect results when calling for example Hogwarts.staff.length later on. In other words, delete would remove the element, but it wouldn’t update the value of length property. Using delete would also mess up your indexing.

So, when deleting values from an object, always first consider whether you’re dealing with object properties or whether you’re dealing with array values, and choose the appropriate strategy based on that.

If you want to experiment with this, you can use this Fiddle as a starting point.

ECMAScript 2015 (or ES6) came with built-in Reflect object. It is possible to delete object property by calling Reflect.deleteProperty() function with target object and property key as parameters:

 Reflect.deleteProperty(myJSONObject, 'regex'); 

which is equivalent to:

 delete myJSONObject['regex']; 

But if the property of the object is not configurable it cannot be deleted neither with deleteProperty function nor delete operator:

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

Object.freeze() makes all properties of object not configurable (besides other things). deleteProperty function (as well as delete operator ) returns false when tries to delete any of it’s properties. If property is configurable it returns true , even if property does not exist.

The difference between delete and deleteProperty is when using strict mode:

 "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 

The delete operator is the best way to do so.

A live example to show:

 var foo = {bar: 'bar'}; delete foo.bar; console.log('bar' in foo); // Logs false, because bar was deleted from foo. 

I personally use Underscore.js for object and array manipulation:

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

This post is very old and I find it very helpful so I decided to share the unset function I wrote in case someone else see this post and think why it’s not so simple as it in PHP unset function.

The reason for writing this new unset function, is to keep the index of all other variables in this hash_map. Look at the following example, and see how the index of “test2” did not change after removing a value from the 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"} 

There are a lot of good answers here but I just want to chime in that when using delete to remove a property in JavaScript, it is often wise to first check if that property exists to prevent errors.

Por exemplo

 var obj = {"property":"value", "property2":"value"}; if (obj && obj.hasOwnProperty("property2")) { delete obj.property2; } else { //error handling } 

Due to the dynamic nature of JavaScript there are often cases where you simply don’t know if the property exists or not. Checking if obj exists before the && also makes sure you don’t throw an error due to calling the hasOwnProperty() function on an undefined object.

Sorry if this didn’t add to your specific use case but I believe this to be a good design to adapt when managing objects and their properties.

Another solution, using 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); 

Using delete method is the best way to do that, as per MDN description, the delete operator removes a property from an object. So you can simply write:

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

The delete operator removes a given property from an object. On successful deletion, it will return true, else false will be returned. However, it is important to consider the following scenarios:

  • If the property which you are trying to delete does not exist, delete will not have any effect and will return true

  • If a property with the same name exists on the object’s prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, delete only has an effect on own properties).

  • Any property declared with var cannot be deleted from the global scope or from a function’s scope.

  • As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function (expression).

  • Functions which are part of an object (apart from the
    global scope) can be deleted with delete.

  • Any property declared with let or const cannot be deleted from the scope within which they were defined. Non-configurable properties cannot be removed. This includes properties of built-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty().

The following snippet gives another simple example:

 var Employee = { age: 28, name: 'abc', 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 

If you want to delete a property deeply nested in the object then you can use the following recursive function with path to the property as the second argument:

 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: {}}} 

Try the following method. Assign the Object property value to undefined . Then stringify the object and parse .

  var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; myObject.regex = undefined; myObject = JSON.parse(JSON.stringify(myObject)); console.log(myObject); 

Using ramda#dissoc you will get a new object without the attribute regex :

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

You can also use other functions to achieve the same effect – omit, pick, …

You can simply delete any property of an object using the delete keyword.

Por exemplo:

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

To remove any property, say key1 , use the delete keyword like this:

 delete obj.key1 

Or you can also use array-like notation:

 delete obj[key1] 

Ref: MDN .

Tente isso

 delete myObject['key']; 

Hello You Can try this simple an sort

 var obj = []; obj.key1 = {name: "John", room: 1234}; obj.key2 = {name: "Jim", room: 1234}; delete(obj.key1); 

Dan’s assertion that ‘delete’ is very slow and the benchmark he posted were doubted. So I carried out the test myself in Chrome 59. It does seem that ‘delete’ is about 30 times slower:

 var iterationsTotal = 10000000; // 10 million var o; var t1 = Date.now(),t2; for (let i=0; i 

Note that I purposedly carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.

Consider creating a new object without the "regex" property because the original object could always be referenced by other parts of your program. Thus you should avoid manipulating it.

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

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

Property Removal in JavaScript

There are many different options presented on this page, not because most of the options are wrong—or because the answers are duplicates—but because the appropriate technique depends on the situation you’re in and the goals of the tasks you and/or you team are trying to fulfill. To answer you question unequivocally, one needs to know:

  1. The version of ECMAScript you’re targeting
  2. The range of object types you want to remove properties on and the type of property names you need to be able to omit (Strings only? Symbols? Weak references mapped from arbitrary objects? These have all been types of property pointers in JavaScript for years now)
  3. The programming ethos/patterns you and your team use. Do you favor functional approaches and mutation is verboten on your team, or do you employ wild west mutative object-oriented techniques?
  4. Are you looking to achieve this in pure JavaScript or are you willing & able to use a 3rd-party library?

Once those four queries have been answered, there are essentially four categories of “property removal” in JavaScript to chose from in order to meet your goals. They are:

Mutative object property deletion, unsafe

This category is for operating on object literals or object instances when you want to retain/continue to use the original reference and aren’t using stateless functional principles in your code. An example piece of syntax in this category:

 '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 

This category is the oldest, most straightforward & most widely supported category of property removal. It supports Symbol & array indexes in addition to strings and works in every version of JavaScript except for the very first release. However, it’s mutative which violates some programming principles and has performance implications. It also can result in uncaught exceptions when used on non-configurable properties in strict mode .

Rest-based string property omission

This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don’t need to account for Symbol keys:

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

Mutative object property deletion, safe

This category is for operating on object literals or object instances when you want to retain/continue to use the original reference while guarding against exceptions being thrown on unconfigurable properties:

 '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 

In addition, while mutating objects in-place isn’t stateless, you can use the functional nature of Reflect.deleteProperty to do partial application and other functional techniques that aren’t possible with delete statements.

Syntax-based string property omission

This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don’t need to account for Symbol keys:

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

Library-based property omission

This category is generally allows for greater functional flexibility, including accounting for Symbols & omitting more than one property in one statement:

 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" 
 const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const { regex, ...other } = myObject; console.log(myObject) console.log(regex) console.log(other) 

Using ES6:

(Destructuring + Spread operator)

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

Using lodash

 import omit from 'lodash/omit'; const prevObject = {test: false, test2: true}; // Removes test2 key from previous object const nextObject = omit(prevObject, 'test2'); 

Using Ramda

 R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3} 

you can use the delete operator as of below.

  var multiverse = { earth1: "Silver Age", earth2: "Golden Age" }; delete multiverse.earth2;//will return true if it finds // Outputs: { earth1: "Silver Age" } console.log(multiverse); 

The delete operator also has a return value. If it succeeds in deleting a property, it will return true. If it fails to delete a property because the property is unwritable it will return false , or if in strict mode it will throw an error.

@johnstock , we can also use JavaScript’s prototyping concept to add method to objects to delete any passed key available in calling object.

Above answers are appreciated.

 var myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; // 1st and direct way delete myObject.regex; // delete myObject["regex"] console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' } // 2 way - by using the concept of JavaScript's prototyping concept Object.prototype.removeFromObjectByKey = function(key) { // If key exists, remove it and return true if(this[key] !== undefined) { delete this[key] return true; } // Else return false return false; } var isRemoved = myObject.removeFromObjectByKey('method') console.log(myObject) // { ircEvent: 'PRIVMSG' } // More examples var obj = { a: 45, b: 56, c: 67} console.log(obj) // { a: 45, b: 56, c: 67 } // Remove key 'a' from obj isRemoved = obj.removeFromObjectByKey('a') console.log(isRemoved); //true console.log(obj); // { b: 56, c: 67 } // Remove key 'd' from obj which doesn't exist var isRemoved = obj.removeFromObjectByKey('d') console.log(isRemoved); // false console.log(obj); // { b: 56, c: 67 }