我有一个平面JS对象:
{a: 1, b: 2, c: 3, ..., z:26}
我想克隆对象除了一个元素:
{a: 1, c: 3, ..., z:26}
最简单的方法是什么(如果可能的话,更倾向于使用es6/7)?
我有一个平面JS对象:
{a: 1, b: 2, c: 3, ..., z:26}
我想克隆对象除了一个元素:
{a: 1, c: 3, ..., z:26}
最简单的方法是什么(如果可能的话,更倾向于使用es6/7)?
当前回答
JavaScript中有一个析构赋值语法可以使用
let obj = {a: 1, b: 2, c: 3, z:26};
let {b, ...rest} = obj;
// skips the "Unused variable" warning
let {b: _, ...rest} = obj;
// removes property based on the dynamic key
const dynamicKey = "b";
let {[dynamicKey]: _, ...rest} = obj;
现代浏览器已经开箱即用地支持它。 参见:JavaScript操作符:解构赋值:对象中的Rest
对于旧的浏览器版本,有一个选项可以使用Babel来支持解构赋值。它将被翻译成:
"use strict";
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;
var y = _objectWithoutProperties(x, ["b"]);
其他回答
上述使用结构化的解决方案确实受到一个事实的影响,即你有一个使用过的变量,如果你使用它,可能会引起ESLint的抱怨。
下面是我的解决方案:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
在大多数平台上(除了IE,除非使用Babel),你还可以这样做:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
您可以为它编写一个简单的helper函数。Lodash有一个同名的类似函数:省略
function omit(obj, omitKey) {
return Object.keys(obj).reduce((result, key) => {
if(key !== omitKey) {
result[key] = obj[key];
}
return result;
}, {});
}
omit({a: 1, b: 2, c: 3}, 'c') // {a: 1, b: 2}
另外,注意它比Object快。然后分配和删除:http://jsperf.com/omit-key
下面是我对Typescript的看法,稍微源自@Paul的回答,并使用reduce代替。
function objectWithoutKey(object: object, keys: string[]) {
return keys.reduce((previousValue, currentValue) => {
// @ts-ignore
const {[currentValue]: undefined, ...clean} = previousValue;
return clean
}, object)
}
// usage
console.log(objectWithoutKey({a: 1, b: 2, c: 3}, ['a', 'b']))
你可以使用lodash库来实现这个目的(如果你需要在一个项目中使用大量的数组/对象数组/对象)。
使用lodash deepclone函数你可以做:
const _obj = _.cloneDeep(obj);
delete _obj.key;
首先将整个对象克隆为新的对象,然后从克隆对象中删除所需的键,这样原始的键就不会受到影响。
如果你正在处理一个巨大的变量,你不希望复制它,然后删除它,因为这将是低效的。
一个简单的带有hasOwnProperty检查的for循环应该可以工作,而且它更适合未来的需求:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}