问题
I have a flat JS object:
{a: 1, b: 2, c: 3, ..., z:26}
I want to clone the object except for one element:
{a: 1, c: 3, ..., z:26}
What\'s the easiest way to do this (preferring to use es6/7 if possible)?
回答1:
If you use Babel you can use the following syntax to copy property b from x into variable b and then copy rest of properties into variable y:
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
and it will be transpiled into:
"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"]);
回答2:
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
or if you accept property to be undefined:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
回答3:
To add to Ilya Palkin's answer: you can even dynamically remove keys:
const x = {a: 1, b: 2, c: 3, z:26};
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object;
return otherKeys;
}
console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};
Demo in Babel REPL
Source:
- https://twitter.com/ydkjs/status/699845396084846592
回答4:
For those who can't use ES6, you can use lodash
or underscore
.
_.omit(x, 'b')
Or ramda
.
R.omit('b', x)
回答5:
I use this one-liner ES6 syntax,
const obj = {a: 1, b: 2, c: 3, d: 4};
const clone = (({b, c, ...others}) => ({...others}))(obj); // remove b and c
console.log(clone);
回答6:
You can write a simple helper function for it. Lodash has a similar function with the same name: omit
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}
Also, note that it is faster than Object.assign and delete then: http://jsperf.com/omit-key
回答7:
Maybe something like this:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
Is this good enough? Or can't c
actually get copied?
回答8:
Using Object Destructuring
const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}
回答9:
Hey seems like you run in to reference issues when you're trying to copy an object then deleting a property. Somewhere you have to assign primitive variables so javascript makes a new value.
Simple trick (may be horrendous) I used was this
var obj = {"key1":"value1","key2":"value2","key3":"value3"};
// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2
console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}
回答10:
Lodash omit
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
回答11:
Here's an option for omitting dynamic keys that I believe has not been mentioned yet:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
is aliased as removedKey
and ignored. newObj
becomes { 2: 2, 3: 3, 4: 4 }
. Note that the removed key does not exist, the value was not just set to undefined
.
回答12:
If you're dealing with a huge variable, you don't want to copy it and then delete it, as this would be inefficient.
A simple for-loop with a hasOwnProperty check should work, and it is much more adaptable to future needs :
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
回答13:
You also can use spread operator to do this
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
回答14:
I recently did it this very simple way:
const obj = {a: 1, b: 2, ..., z:26};
just using spread operator to separate the unwanted property:
const {b, ...rest} = obj;
...and object.assign to take only the 'rest' part:
const newObj = Object.assign({}, {...rest});
回答15:
What about this? I never found this patter around but I was just trying to exclude one or more properties without the need of creating an extra object. This seems to do the job but there are some side effects I'm not able to see. For sure is not very readable.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
回答16:
I accomplished it this way, as an example from my Redux reducer:
const clone = { ...state };
delete clone[action.id];
return clone;
In other words:
const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey] // or use clone.unwantedKey or any other applicable syntax
return clone // the original object without the unwanted key
回答17:
The solutions above using structuring do suffer from the fact that you have an used variable, which might cause complaints from ESLint if you're using that.
So here are my solutions:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
On most platforms (except IE unless using Babel), you could also do:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
来源:https://stackoverflow.com/questions/34698905/how-can-i-clone-a-javascript-object-except-for-one-key