【发布时间】:2015-02-08 15:37:09
【问题描述】:
在客户端,我使用了一个复杂的 Javascript 对象。但是当将它发送到服务器时,我只想发送它的一部分。
我想克隆它,但只克隆我需要的那些部分。我想要一个功能,就像
var wireFriendly = reduce(original, "id, name, related.id, related.name");
// or
var wireFriendly = reduce(original, ["id", "name", "related.id", "related.name"]);
到目前为止我做了什么
我已经创建了这个函数的大部分,当对象图只包含对象时,它可以满足我的要求。如果我里面有数组,它将无法工作。但这是我目前得到的:
function (entity, keepMembersList) {
// check entity that it's not undefined, null and that it's an actual Object instance
if (Object.prototype.toString.call(entity) !== "[object Object]")
{
throw "'entity' parameter should be a non-null object."
}
// code in switch statement only normalizes function arguments when
// they are provided either as a string or as an array of string
switch (Object.prototype.toString.call(keepMembersList))
{
case '[object String]':
keepMembersList = keepMembersList.split(',').map(function (value) {
return value.trim();
});
case '[object Array]':
keepMembersList = keepMembersList.map(function (value) {
return value.split(".");
});
break;
default:
throw "Parameter 'keepMembersList' should either be a comma delimited list of members' names to keep or an array of them.";
}
// from this point on, cloning is taking place
var result = {};
for (var i = 0; i < keepMembersList.length; i++)
{
for (var j = 0, r = result, e = entity; j < keepMembersList[i].length - 1; j++)
{
// ----------------------------------------------------------
// this part should be changed to also detect array notations
// ----------------------------------------------------------
r = r[keepMembersList[i][j]] = r[keepMembersList[i][j]] || {};
e = e[keepMembersList[i][j]];
}
r[keepMembersList[i][j]] = e[keepMembersList[i][j]];
}
return result;
}
我希望它也适用于这两个示例
// clone all array elements with specific members
var wireFriendly = reduce(original, "id, name, related[].id, related[].name");
// clone specific array element with specific members
var wireFriendly = reduce(original, ["id", "name", "related[0].id", "related[0].name"]);
但我至少可以接受第一个示例,其中数组的所有元素都被减少了成员。第二个仅克隆特定数组元素的示例对我的情况来说并不重要,但我想拥有它也会很棒。当然,在这种情况下,结果数组的索引不必匹配,否则我们会遇到未定义的元素:
//in case related[3].id would be specified we'd end up with
related:[undefined, undefined, undefined, { id: 1 }];
示例数据
将此对象用作需要部分克隆的原始实体:
var original = {
"related":[{
"related":[],
"id":1759807323,
"name":"Related name",
"interest":{
"id":1314962015,
"name":"Ideas",
"isLocked":false,
"isPrivileged":false
},
"details":"Lengthy related details that will not be sent to server"
}],
"name":"My name",
"interest":{
"id":1314962015,
"name":"Ideas",
"isLocked":false,
"isPrivileged":false
},
"details":"Some lengthy details"
}
您可以在this JSFiddle 中使用此函数测试一个工作示例。
【问题讨论】:
-
你能覆盖
toJSON并返回你需要的吗?你在实现你想要的东西方面还有什么问题? -
附带说明,我认为使用 typeof 命令而不是 toString 方法更可靠。有人可以覆盖 toString。但他们不能覆盖 typeof。
-
你能举一个你的
originalvar 的例子吗? -
@Eyal:这不是... Null、数组、日期都作为对象返回。因此,我使用
toString来确定某些东西正是所需的类型。 -
@helpermethod:
_.pick仅适用于第一级对象成员。它不适用于深度(er)对象图。我也不确定它如何处理数组成员...
标签: javascript cloning