admin管理员组文章数量:1356515
I have a javascript object that represents form fields. about 70% of these fields have to be copied in some objects for sending to server, other fields are for UI usage. Presently I clone objects by manually creating assignments for each field, that result in rather not nice structures, as shown below. Note that I would keep field names identical for parts being copied.
var contData = {
ContainerType: data.ContainerType,
ProjectIds: data.ProjectIds,
PrivateToProjects: data.PrivateToProjects,
DimensionType:data.DimensionType,
MetricsX: data.MetricsX,
MetricsY: data.MetricsY,
Parent:data.Parent,
ContainerName:data.Prefix
};
What would be the best way to code cloning part of object, just specifying list of fields to clone/not to clone, such as some useful helper function?
I also use angular and jquery.
I have a javascript object that represents form fields. about 70% of these fields have to be copied in some objects for sending to server, other fields are for UI usage. Presently I clone objects by manually creating assignments for each field, that result in rather not nice structures, as shown below. Note that I would keep field names identical for parts being copied.
var contData = {
ContainerType: data.ContainerType,
ProjectIds: data.ProjectIds,
PrivateToProjects: data.PrivateToProjects,
DimensionType:data.DimensionType,
MetricsX: data.MetricsX,
MetricsY: data.MetricsY,
Parent:data.Parent,
ContainerName:data.Prefix
};
What would be the best way to code cloning part of object, just specifying list of fields to clone/not to clone, such as some useful helper function?
I also use angular and jquery.
Share Improve this question asked May 27, 2014 at 10:03 onkamionkami 9,44120 gold badges104 silver badges200 bronze badges 1- Yes. Have you tried writing such a helper function? It's quite trivial actually. I don't think there already is one in angular or jquery. – Bergi Commented May 27, 2014 at 10:20
4 Answers
Reset to default 10After ES6, you could
let { ContainerType, ProjectIds } = data // the fields you want
let partiallyCopy = { ContainerType, ProjectIds }
console.log(partiallyCopy) // { ContainerType: "...", ProjectIds: "..." }
And if you need most fields, you could
let { ContainerType, ProjectIds, ...rest } = data // the fields you don't want
let partiallyCopy = rest
console.log(partiallyCopy) // the object excludes ContainerType and ProjectIds
You could create a custom function to clone your object partially with a filter function.
It could be something like this as the very simple version.
function filteredClone(sourceObj, filterFunction){
var destObj = {};
for(var i in sourceObj){
if(filterFunction(sourceObj[i])){
destObj[i] = sourceObj[i];
}
}
return destObj;
}
And you can call it like the following assuming that you don't want "name" and "surname" fields to be copied.
var dest = filteredClone(source, function(v){
return ["name","surname"].indexOf(v) !== -1;
});
There are a couple of more sophisticated samples in the answers to the following question.
Deep clone without some fields
Dan's destructuring answer is good, but it still requires an assignment, making it less than ideal (however still possible) for lambda, or arrow-style, concatenation. It remains a great way to filter out object fields when passing parameters to a functions, for instance
Here's an alternative that you can embed in an expression and that doesn't use assignment side-effects:
wanted = ['ContainerType', 'ProjectIds', 'PrivateToProjects',
'DimensionType', 'MetricsX', 'MetricsY', 'Parent', 'Prefix']
contData = Object.fromEntries(Object.entries(data).filter(x => wanted.includes(x[0]))))
The only state this requires is the wanted
fields. If you want to preserve most fields in data
, you can always use notWanted
instead and negate the filter
condition.
One method is to define properties on objects. IE9 is the first IE to support this.
var obj = {};
Object.defineProperty(obj, "no1", {enumerable: false, value: "", writable: true, configurable: true});
Object.defineProperty(obj, "no2", {enumerable: false, value: "", writable: true, configurable: true});
obj.yes1 = "foo";
obj.yes2 = "bar";
obj.no1 = "baz";
obj.no2 = "quux";
jsfiddle
99.9% of clone functions will loop over the keys, and only enumerable keys will show up, so they only copy enumerable keys. This is the same reason why, e.g. toString
doesn't show up when looping over an object's keys.
This can be abstracted to allow defining data and temporary values.
function makeType(description, data) {
if (arguments.length === 1) {
return function (data) {
return makeType.call(this, description, data);
};
}
var obj = {};
data = data || {};
for (var key in description) {
if (description[key] === true) {
obj[key] = data[key]
} else {
Object.defineProperty(obj, key, {
enumerable: false,
value: data[key],
writable: true,
configurable: true
});
}
}
return obj;
}
var makeYesNo = makeType({
yes1: true,
yes2: true,
no1: false,
no2: false
});
var obj = makeYesNo({
yes1: "foo",
yes2: "bar",
no1: "baz",
no2: "quux"
})
fiddle
本文标签: Elegant way to code partially copy objects in JavascriptStack Overflow
版权声明:本文标题:Elegant way to code partially copy objects in Javascript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744023258a2577594.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论