JavaScript: chave de renomeação de object

Existe uma maneira inteligente (isto é, otimizada) de renomear uma chave em um object javascript?

Uma maneira não otimizada seria:

o[ new_key ] = o[ old_key ]; delete o[ old_key ]; 

    A maneira mais completa (e correta) de fazer isso seria, eu acredito:

     if (old_key !== new_key) { Object.defineProperty(o, new_key, Object.getOwnPropertyDescriptor(o, old_key)); delete o[old_key]; } 

    Esse método garante que a propriedade renomeada se comporte de maneira idêntica à original.

    Além disso, parece-me que a possibilidade de envolvê-lo em uma function / método e colocá-lo em Object.prototype é irrelevante em relação à sua pergunta.

    Você poderia envolver o trabalho em uma function e atribuí-lo ao protótipo do Object . Talvez use o estilo de interface fluente para fazer várias renomeações fluírem.

     Object.prototype.renameProperty = function (oldName, newName) { // Do nothing if the names are the same if (oldName == newName) { return this; } // Check for the old property name to avoid a ReferenceError in strict mode. if (this.hasOwnProperty(oldName)) { this[newName] = this[oldName]; delete this[oldName]; } return this; }; 

    ECMAScript 5 específico

    Eu gostaria que a syntax não fosse tão complexa, mas definitivamente é legal ter mais controle.

     Object.defineProperty( Object.prototype, 'renameProperty', { writable : false, // Cannot alter this property enumerable : false, // Will not show up in a for-in loop. configurable : false, // Cannot be deleted via the delete operator value : function (oldName, newName) { // Do nothing if the names are the same if (oldName == newName) { return this; } // Check for the old property name to // avoid a ReferenceError in strict mode. if (this.hasOwnProperty(oldName)) { this[newName] = this[oldName]; delete this[oldName]; } return this; } } ); 

    Caso alguém precise renomear uma lista de propriedades:

     function renameKeys(obj, newKeys) { const keyValues = Object.keys(obj).map(key => { const newKey = newKeys[key] || key; return { [newKey]: obj[key] }; }); return Object.assign({}, ...keyValues); } 

    Uso:

     const obj = { a: "1", b: "2" }; const newKeys = { a: "A", c: "C" }; const renamedObj = renameKeys(obj, newKeys); console.log(renamedObj); // {A:"1", b:"2"} 

    Eu gostaria apenas de usar o modo ES6(ES2015) !

    Precisamos nos manter atualizados com os tempos!

     const old_obj = { k1: `111`, k2: `222`, k3: `333` }; console.log(`old_obj =\n`, old_obj); // {k1: "111", k2: "222", k3: "333"} /** * @author xgqfrms * @description ES6 ...spread & Destructuring Assignment */ const { k1: kA, k2: kB, k3: kC, } = {...old_obj} console.log(`kA = ${kA},`, `kB = ${kB},`, `kC = ${kC}\n`); // kA = 111, kB = 222, kC = 333 const new_obj = Object.assign( {}, { kA, kB, kC } ); console.log(`new_obj =\n`, new_obj); // {kA: "111", kB: "222", kC: "333"} 

    Se você está transformando seu object de origem, o ES6 pode fazer isso em uma linha.

    Exclua Object.assign (o, {[newKey]: o [oldKey]}) [oldKey];

    Eu faria algo assim:

     function renameKeys(dict, keyMap) { return _.reduce(dict, function(newDict, val, oldKey) { var newKey = keyMap[oldKey] || oldKey newDict[newKey] = val return newDict }, {}) } 

    Se você não quiser alterar seus dados, considere esta function …

     renameProp = (oldProp, newProp, {[oldProp]:old, ...others}) => ({ [newProp]: old, ...others }) 

    Uma explicação completa por Yazeed Bzadough https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd


    Eu diria que seria melhor, do ponto de vista conceitual, deixar o object antigo (o do serviço da web) como está e colocar os valores necessários em um novo object. Eu estou supondo que você está extraindo campos específicos em um ponto ou outro de qualquer maneira, se não no cliente, pelo menos no servidor. O fato de você escolher usar nomes de campo iguais aos do serviço da Web, apenas em minúsculas, não altera isso. Então, eu aconselho a fazer algo assim:

     var myObj = { field1: theirObj.FIELD1, field2: theirObj.FIELD2, (etc) } 

    Claro, estou fazendo todo tipo de suposições aqui, o que pode não ser verdade. Se isso não se aplica a você, ou se é muito lento (é isso? Eu não testei, mas eu imagino que a diferença diminui à medida que o número de campos aumenta), por favor, ignore tudo isso 🙂

    Se você não quer fazer isso, e você só tem que suportar navegadores específicos, você também pode usar os novos getters para também retornar “maiúsculas (campo)”: veja http://robertnyman.com/2009/05/28 / getters-and-setters-com-javascript-code-samples-e-demos / e os links nessa página para mais informações.

    EDITAR:

    Incrivelmente, isso também é quase duas vezes mais rápido, pelo menos no meu FF3.5 no trabalho. Veja: http://jsperf.com/spiny001

    Pessoalmente, a maneira mais eficaz de renomear chaves no object sem implementar plugins e rodas extra-pesados:

     var str = JSON.stringify(object); str = str.replace(/oldKey/g, 'newKey'); str = str.replace(/oldKey2/g, 'newKey2'); object = JSON.parse(str); 

    Você também pode envolvê-lo no try-catch se o seu object tiver uma estrutura inválida. Funciona perfeitamente 🙂

    Embora isso não forneça exatamente uma solução melhor para renomear uma chave, ela fornece uma maneira rápida e fácil do ES6 de renomear todas as chaves em um object sem alterar os dados que contêm.

     let b = {a: ["1"], b:["2"]}; Object.keys(b).map(id => { b[`root_${id}`] = [...b[id]]; delete b[id]; }); console.log(b); 

    Algumas das soluções listadas nesta página têm alguns efeitos colaterais:

    1. afeta a posição da chave no object, adicionando-a ao fundo (se isso é importante para você)
    2. não funcionaria no IE9 + (novamente, se isso é importante para você)

    Aqui está uma solução que mantém a posição da chave no mesmo lugar e é compatível com o IE9 +, mas tem que criar um novo object e pode não ser a solução mais rápida:

     function renameObjectKey(oldObj, oldName, newName) { const newObj = {}; Object.keys(oldObj).forEach(key => { const value = oldObj[key]; if (key === oldName) { newObj[newName] = value; } else { newObj[key] = value; } }); return newObj; } 

    Por favor note: IE9 pode não suportar paraEach em modo estrito