JavaScript: Object Rename Key

JavaScript: Object Rename Key

Is there a clever (i.e. optimized) way to rename a key in a javascript object?
A non-optimized way would be:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];

Solutions/Answers:

Solution 1:

The most complete (and correct) way of doing this would be, I believe:

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

This method ensures that the renamed property behaves identically to the original one.

Also, it seems to me that the possibility to wrap this into a function/method and put it into Object.prototype is irrelevant regarding your question.

Solution 2:

You could wrap the work in a function and assign it to the Object prototype. Maybe use the fluent interface style to make multiple renames flow.

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

Related:  How to check if a DIV is scrolled all the way to the bottom with jQuery

I wish the syntax wasn’t this complex but it is definitely nice having more control.

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

Solution 3:

If you’re mutating your source object, ES6 can do it in one line.

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

Or two lines if you want to create a new object.

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

Solution 4:

In case someone needs to rename a list of properties:

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

Usage:

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

Solution 5:

I would like just using the ES6(ES2015) way!

we need keeping up with the times!

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

demo screen shortcut

Solution 6:

If you don’t want to mutate your data, consider this function…

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

A thorough explanation by Yazeed Bzadough
https://medium.com/front-end-hacking/immutably-rename-object-keys-in-javascript-5f6353c7b6dd

Related:  jQuery event that triggers after CSS is loaded?