javascript - splice - typescript delete object




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

2 (ES6)

Para quem precisa ...

Para completar a resposta @Koen neste tópico, caso você queira remover uma variável dinâmica usando a sintaxe de propagação, você pode fazer assim:

const key = 'a';

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

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

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


ATUALIZAÇÃO :
Existem algumas maneiras comuns de remover uma propriedade de um objeto.
Cada um tem seus prós e contras ( confira esta comparação de desempenho ):

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
legível e curto, no entanto, pode não ser a melhor escolha se você estiver operando em um grande número de objetos, pois seu desempenho não é otimizado.

delete obj[key];


Reassignment
Mais de 2 vezes mais rápido do quedelete, no entanto, a propriedadenãoéexcluída e pode ser iterada.

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


Operador de distribuição
EsteES6operador nos permite retornar um novo objeto, excluindo quaisquer propriedades, sem alterar o objeto existente. A desvantagem é que ele tem o pior desempenho do que foi mencionado acima e não é recomendado para ser usado quando você precisa remover muitas propriedades de cada vez.

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

Digamos que eu crie um objeto 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"
};

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


A delete operador é inesperadamente lenta!

Olhe para o benchmark .

Excluir é a única maneira verdadeira de remover as propriedades do objeto 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 objeto 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 objeto, conectado a essa 'chave'.

Use delete , quando você estiver passando o objeto 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 métodos.

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 memória!

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 memória, enquanto obj[prop] = undefined simplesmente define o valor de prop para undefined que o deixa imóvel na memória. 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 memória cara (causando o congelamento da página) e, potencialmente, um erro de falta de memória. 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 vazamento de memória 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 memória. 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 memória, 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 objetos 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 objetivo 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 polimorfismo. O polimorfismo é quando se atribuem os mesmos tipos diferentes de variáveis ​​/ slots em um objeto, 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 memória. 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 polimorfismo 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 polimorfismo 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 polimorfismo. 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 polimorfismo 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 polimorfismo enquanto bar[1] = undefined faz. Portanto, deve-se sempre, sempre que possível, usar o tipo correspondente para seus objetos, de modo a não causar acidentalmente polimorfismo. 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 polimorfismo desnecessário seja bom, reescrever 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.


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

Para qualquer pessoa interessada em ler mais sobre isso, o usuário do kangax escreveu uma postagem de blog incrivelmente detalhada sobre a instrução delete em seu blog, Understanding delete . É altamente recomendado.


Outra alternativa é usar a biblioteca Underscore.js .

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

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

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

Retorna uma cópia do objeto, 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.


Pergunta antiga, resposta moderna. Usando a desestruturação de objetos, 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);

Este post é muito antigo e eu acho muito útil, então eu decidi compartilhar a função unset que eu escrevi no caso de alguém ver este post e pensar por que não é tão simples como no PHP unset função.

A razão para escrever esta 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 depois de 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"}

Há muitas boas respostas aqui, mas eu só quero dizer 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, 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 lança um erro devido a chamar a função hasOwnProperty () em um objeto indefinido.

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


Olá, você pode tentar esta simples uma espécie

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);

Se você quiser excluir uma propriedade profundamente aninhada no objeto, poderá usar a seguinte função recursiva com o 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: {}}}

Tente isso

delete myObject['key'];

Usando o ES6:

(Operador de Destruição + Spread)

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

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.


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

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

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


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

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

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

console.log(newMyObject);


ECMAScript 2015 (ou ES6) veio com built-in Reflect objeto. É 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');

o que equivale 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() faz com que todas as propriedades do objeto não sejam configuráveis ​​(além de outras coisas). deletePropertyfunction (assim como developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) 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é quando se usa 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


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ê quiser criar um novo objeto sem a chave especificada, basta atribuir a função reduce 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);


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, ...


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, senão 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, então, após a exclusão, o objeto usará a propriedade da cadeia de protótipos (em outras palavras, a exclusão só terá efeito 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 (se isso faz 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 delete.

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

O seguinte trecho dá outro exemplo simples:

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

Para mais informações e mais exemplos, acesse o link abaixo:

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…







object-properties