是否有一个聪明的(即优化)方法重命名一个关键在javascript对象?

一种非优化的方式是:

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

当前回答

这是我对pomber函数做的一个小修改; 为了能够获取一个对象数组而不是单独的对象,你也可以激活索引。此外,“键”也可以由数组分配

function renameKeys(arrayObject, newKeys, index = false) {
    let newArray = [];
    arrayObject.forEach((obj,item)=>{
        const keyValues = Object.keys(obj).map((key,i) => {
            return {[newKeys[i] || key]:obj[key]}
        });
        let id = (index) ? {'ID':item} : {}; 
        newArray.push(Object.assign(id, ...keyValues));
    });
    return newArray;
}

test

const obj = [{ a: "1", b: "2" }, { a: "5", b: "4" } ,{ a: "3", b: "0" }];
const newKeys = ["A","C"];
const renamedObj = renameKeys(obj, newKeys);
console.log(renamedObj);

其他回答

您可以将工作包装在一个函数中,并将其分配给Object原型。也许可以使用流畅的界面样式使多个重命名流动。

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 Specific

我希望语法不是这么复杂,但它肯定是很好的有更多的控制。

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

我想说,从概念的角度来看,保持旧对象(来自web服务的对象)原样,并将所需的值放在新对象中会更好。我假设您在某个地方提取特定的字段,如果不是在客户机上,那么至少是在服务器上。事实上,您选择使用与web服务相同的字段名,只是小写,这并没有真正改变这一点。所以,我建议你这样做:

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

当然,我在这里做了各种各样的假设,这可能是不正确的。如果这对你不适用,或者它太慢了(是吗?我还没有测试过,但我想随着字段数量的增加,差异会越来越小),请忽略所有这些:)

如果你不想这样做,并且你只需要支持特定的浏览器,你也可以使用新的getter来返回“大写(字段)”。:更多信息请参见http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/和该页面上的链接。

编辑:

令人难以置信的是,这也几乎是两倍的速度,至少在我的FF3.5工作。参见:http://jsperf.com/spiny001

一般来说,如果你想获得一个新的对象(不改变原来的对象),根据keyMap重命名键-你可以使用以下基于lodash mapKeys的实现:

const {mapKeys} = require('lodash');
const renameKeys = (obj, keyMap) => _.mapKeys(obj, (value, key) => keyMap[key] || key);

使用的例子:

renameKeys({a: 1, b: 2, c: 3}, {c: 'p', a: 'm'})
> {m: 1, b: 2, p: 3}

这里的大多数答案都无法维持JS对象键值对的顺序。例如,如果您在屏幕上有一种希望修改的对象键-值对形式,那么保持对象条目的顺序就很重要。

ES6循环JS对象并将键值对替换为具有修改过的键名的新键值对的方法如下:

let newWordsObject = {};

Object.keys(oldObject).forEach(key => {
  if (key === oldKey) {
    let newPair = { [newKey]: oldObject[oldKey] };
    newWordsObject = { ...newWordsObject, ...newPair }
  } else {
    newWordsObject = { ...newWordsObject, [key]: oldObject[key] }
  }
});

该解决方案通过在旧条目的位置上添加新条目来保留条目的顺序。

如果你要改变源对象,ES6可以在一行中完成。

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

如果你想创建一个新对象,可以用两行。

const newObject = {};
delete Object.assign(newObject, o, {[newKey]: o[oldKey] })[oldKey];