编辑:
哦,我刚刚意识到,您想tasks
合并milestone
并milestone
合并到项目中。
在这种情况下,您必须合并一个合并的对象。
但是像@Amberlamps 和@Elias Van Ootegem 建议的那样,从一开始就设置这样的对象结构会更容易。
我更新了答案
Edit2:更改了类型检查以使用instanceof
,因为{}.toString.call(o)
返回对象 ClassName,对于 nodeElement 和“[object global]”可以是任何东西window
您可以编写一个合并函数,将多个对象的属性合并为一个。
var merge = (function () {
var initThis = this;
return function () {
var len = arguments.length - 1,
srt, tmp;
if ("function" === typeof arguments[arguments.length - 1]) srt = arguments[arguments.length - 1];
else {
srt = function (a, b, prop) {
if (!prop) return a;
return a[prop];
};
len++;
}
var merge = this === initThis ? {} : this;
for (var i = 0; i < len; i++) inner(arguments[i], merge);
function inner(obj2, obj1) {
if (obj2 instanceof Array) {
if (!obj1) obj1 = [];
if (typeof obj1 != "object") obj1 = (tmp = srt(obj1, obj2, null), tmp) === obj2 ? [] : tmp;
for (var i = 0; i < obj2.length; i++) if (!obj1[i] && typeof obj2[i] == "object") obj1[i] = inner(obj2[i]);
else if (obj1[i] && typeof obj2[i] == "object") obj1[i] = inner(obj2[i], obj1[i]);
else if (obj1[i]) obj1[i] = srt(obj1, obj2, i) || obj1[i];
else obj1[i] = obj2[i];
} else if (obj2 instanceof Object) {
if (!obj1) obj1 = {};
if (typeof obj1 != "object") obj1 = (tmp = srt(obj1, obj2, null), tmp) === obj2 ? {} : tmp; //If obj2 is returned, set to empty obj to allow deep cloning
for (var prop in obj2) {
var isObj = "object" === typeof obj2[prop];
if (!obj1[prop] && isObj) obj1[prop] = inner(obj2[prop]);
else if (obj1[prop] && isObj) obj1[prop] = inner(obj2[prop], obj1[prop]);
else if (obj1[prop]) obj1[prop] = srt(obj1, obj2, prop) || obj1[prop];
else obj1[prop] = obj2[prop];
}
} else {
throw new SyntaxError ("expected " + obj2 + " to be of type object");
}
return obj1;
}
return merge;
};
})();
合并函数接受n个参数,其中最后一个可以是消歧函数,当当前合并对象的2个属性相同时调用该函数。
使用 3 个参数调用此消歧函数:
函数的返回值将分配给当前的合并属性。
例如return a[prop]
,如果存在冲突,将始终分配第一个对象的值。
如果没有函数作为最后一个参数传递,则默认行为是:保留第一个 Object 的值。
现在我们必须调用merge
and milestone
,tasks
然后merge
project
使用合并的milestone
Object,它看起来像这样。
project = {id: 1};
milestone = { id: 1, name: "milestone a" };
tasks = [{ name: 'task a' }, { name: 'task b' }];
var merged = merge (project,{milestone: merge (milestone , {tasks:tasks} )});
//^^^ mergeception
//^^^ Wrap it because you want the complete 'tasks' object, not merge the properties this time.
console.log (JSON.stringify(merged));
/* {
"id": 1,
"milestone": { //<- milestone in merged/project
"id": 1,
"name": "milestone a",
"tasks": [{ //<- tasks in milestone
"name": "task a"
}, {
"name": "task b"
}]
}
} */
你可以看到它返回一个合并的对象。
这是一个关于 JSBin的演示
或者如果你想要 jQuery 的方式..
var merged = $.extend(project, {milestone : $.extend (milestone, {tasks:tasks}) });