问题
I need a simple function to map a list of primitive properties from one object to another. I wrote one myself, but I guess there's already a proven method to achieve this.
var mapProperties = function (props, from) {
var to = {};
for (var i = 0; i < props.length; i++) {
to[props[i]] = from[props[i]];
}
return to;
}
Then use the function like:
var fromObj = {
foo: "foo",
bar: 1
}
var toObj = mapProperties(['foo', 'bar'], fromObj);
Any better ideas?
回答1:
If you are not looking to DeepClone, Then you can use Object.assign to copy the values of all enumerable own properties from one or more source objects to a target object.
var fromObj = {
foo: "foo",
bar: 1
}
var targetObject = Object.assign({}, fromObj);
console.log(targetObject);
For Deep Cloning, you can use the JSON.parse and JSON.stringify methods.
var fromObj = {
foo: "foo",
bar: 1,
deepClone : {
newProp : 2
}
}
var targetObject = JSON.parse(JSON.stringify(fromObj));
targetObject.deepClone.newProp = 4;
console.log(targetObject);
回答2:
There are a couple ways to clone. If all you need is a shallow clone (your object only contains one level of primitives), Object.assign() is a handy way to do it:
const fromObj = { a: 1, b: 2, c: 3 };
const toObj = Object.assign({}, fromObj);
The Object.assign() function basically says "Assign all properties from the other objects to the first one". By making the first one an empty object, it is effectively a clone.
If you need a more controlled copy, you can use Object.keys() so you don't have manually have an array that lists properties:
// concise example using reduce and assign
const cloneA = obj => Object.keys(obj).reduce((result, key) => Object.assign(result, { [key]: obj[key] }), {});
// using a for-loop
const cloneB = obj => {
const result = {};
const keys = Object.keys(obj);
for(let i in keys) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
const fromObj = { a: 1, b: 2, c: 3 };
console.log(cloneA(fromObj));
console.log(cloneB(fromObj));
If you need to deal with anything other then primitives, you want a deep clone function. There are lots of libraries with them out there, so I won't re-implement one here, but basically it's a recursive version of one of my clone functions that checks if it's a primitive or not before the copy.
回答3:
Here's an implementation that only copies primitives, following the convention of Object.assign():
function filterPrimitives (key) {
return !(this[key] instanceof Object)
}
function clonePrimitives (target) {
var sources = Array.from(arguments).slice(1)
sources.forEach(function (source) {
var ownKeys = Object.getOwnPropertyNames(source)
var primitiveKeys = ownKeys.filter(filterPrimitives, source)
primitiveKeys.forEach(function (key) {
target[key] = source[key]
})
})
return target
}
var target = {};
var source = {
a: 'test',
b: /test/,
c: 5,
d: null,
e: undefined,
f: {},
g: []
}
clonePrimitives(target, source, { a: 'override' })
console.log(target)
If you want a more efficient approach, use for loops instead of forEach():
function clonePrimitives (target) {
var i, j, source, ownKeys, key
for (i = 1; i < arguments.length; i++) {
source = arguments[i]
ownKeys = Object.getOwnPropertyNames(source)
for (j = 0; j < ownKeys.length; j++) {
key = ownKeys[j]
if (!(source[key] instanceof Object)) {
target[key] = source[key]
}
}
}
return target
}
var target = {};
var source = {
a: 'test',
b: /test/,
c: 5,
d: null,
e: undefined,
f: {},
g: []
}
clonePrimitives(target, source, { a: 'override' })
console.log(target)
And lastly, an equivalent ES6 approach that makes things a little nicer:
function clonePrimitives (target) {
for (let source of Array.from(arguments).slice(1)) {
for (let key of Object.getOwnPropertyNames(source)) {
if (!(source[key] instanceof Object)) {
target[key] = source[key]
}
}
}
return target
}
let target = {};
let source = {
a: 'test',
b: /test/,
c: 5,
d: null,
e: undefined,
f: {},
g: []
}
clonePrimitives(target, source, { a: 'override' })
console.log(target)
来源:https://stackoverflow.com/questions/44805944/is-there-a-proper-way-to-clone-certain-primitive-properties-of-an-object-in-java