有没有一种聪明(即优化)的方式来重命名JavaScript对象中的键?
非优化的方法如下:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
有没有一种聪明(即优化)的方式来重命名JavaScript对象中的键?
非优化的方法如下:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
我认为最完整(且正确)的做法是:
if (old_key !== new_key) {
Object.defineProperty(o, new_key,
Object.getOwnPropertyDescriptor(o, old_key));
delete o[old_key];
}
这种方法确保重命名的属性与原始属性表现完全相同。
另外,对我来说,将其封装到函数/方法中并将其放入Object.prototype
中的可能性与您的问题无关。
if (old_key !== new_key)
变为:
if (old_key !== new_key && o[old_key])
- joseo
)。 - Valeriu Paloş如果你要改变源对象,ES6可以在一行代码中实现。
delete Object.assign(o, {[newKey]: o[oldKey] })[oldKey];
如果您想要创建一个新的对象,则可以使用两行。
const newObject = {};
delete Object.assign(newObject, o, {[newKey]: o[oldKey] })[oldKey];
newKey
周围有方括号[]
?实际上即使没有这个也能运行。 - Soumya Kanti你可以将这段代码包装在一个函数中,并将其赋值给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 特定
我希望语法不要这么复杂,但更多的控制确实很好。
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;
}
}
);
Object.defineProperty
将属性标记为不可枚举。 - ChaosPandionhasOwnProperty
来检查属性并在for ... in
循环中使用,那么扩展对象有什么关系呢? - David Tang如果有人需要重命名一系列的属性:
function renameKeys(obj, newKeys) {
const keyValues = Object.keys(obj).map(key => {
const newKey = newKeys[key] || key;
return { [newKey]: obj[key] };
});
return Object.assign({}, ...keyValues);
}
使用方法:
const obj = { a: "1", b: "2" };
const newKeys = { a: "A", c: "C" };
const renamedObj = renameKeys(obj, newKeys);
console.log(renamedObj);
// {A:"1", b:"2"}
my_object_property
转换为myObjectProperty
,但是,如果我的属性只有一个单词,那么该键将被删除。+1 - blueprintchris为每个键添加前缀:
const obj = {foo: 'bar'}
const altObj = Object.fromEntries(
Object.entries(obj).map(([key, value]) =>
// Modify key here
[`x-${key}`, value]
)
)
// altObj = {'x-foo': 'bar'}
我们需要跟上时代的步伐!
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"}
const old_obj = {
k1: `111`,
k2: `222`,
k3: `333`
};
// destructuring, with renaming. The variable 'rest' will hold those values not assigned to kA, kB, or kC.
const {
k1: kA,
k2: kB,
k3: kC,
...rest
} = old_obj;
// now create a new object, with the renamed properties kA, kB, kC;
// spread the remaining original properties in the 'rest' variable
const newObj = {kA, kB, kC, ...rest};
对于一个键,它可以非常简单,例如:
const { k1: kA, ...rest } = old_obj;
const new_obj = { kA, ...rest }
您可能更喜欢一种更“传统”的风格:
const { k1, ...rest } = old_obj
const new_obj = { kA: k1, ...rest}
renameProp = (oldProp, newProp, { [oldProp]: old, ...others }) => ({
[newProp]: old,
...others
})
这是一个支持typescript的版本:
// These generics are inferred, do not pass them in.
export const renameKey = <
OldKey extends keyof T,
NewKey extends string,
T extends Record<string, unknown>
>(
oldKey: OldKey,
newKey: NewKey extends keyof T ? never : NewKey,
userObject: T
): Record<NewKey, T[OldKey]> & Omit<T, OldKey> => {
const { [oldKey]: value, ...common } = userObject
return {
...common,
...({ [newKey]: value } as Record<NewKey, T[OldKey]>)
}
}
它将防止您覆盖现有的键或将其重命名为相同的内容
这里大多数答案都没有保持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] }
}
});
该解决方案通过在旧条目的位置添加新条目来保留条目的顺序。
_.mapKeys
。
var user = {
name: "Andrew",
id: 25,
reported: false
};
var renamed = _.mapKeys(user, function(value, key) {
return key + "_" + user.id;
});
console.log(renamed);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>