nnnnnn
の回答に加えて。上記は浅いコピーのみを行うことに注意してください。
つまりObject
、参照によってコピーされます。
これは、もう少し高度なマージ機能です。後でもう少し詳しく説明します。
マージ機能
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 (null === 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) {
var type = ({}).toString.call(obj2);
if (type == "[object 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 if (type == "[object 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] = (function (i) {
return srt(obj1, obj2, i)
})(i) || obj1[i];
else obj1[i] = obj2[i];
}
return obj1;
}
return merge;
};
})();
サンプルデータ
var target = {
unique: "a",
conflict: "target",
object: {
origin: "target"
},
typeConflict: "primitive",
arr: [1, 5, 3, 6]
};
var mergeFrom = {
other: "unique",
conflict: "mergeFrom",
object: {
origin: "mergeFrom",
another: "property"
},
typeConflict: ["object"],
arr: [3, 2, 7, 1]
};
使用法
マージ関数はn
パラメーターを受け入れます。
そして、渡されたすべてのオブジェクトを 1 つにマージして返します。
.call
オブジェクトがマージさ れるコンテキストを設定できます。
conflict
関数は最後の引数として渡すことができます。プロパティが既に存在する場合に呼び出されます。
3 つのパラメーターで呼び出されます。
a
、b
、prop
ここで
a
は最初のオブジェクト
b
です。2 番目のオブジェクト
prop
は現在マージされているプロパティです。
タイプの競合がある場合。たとえば、値 1 は aprimitive
で、値 2 は an です。Object
prop
はnull
呼び出しの例
スコープ以外のコンテキストでマージ関数を呼び出すと、オブジェクトがマージされます。
merge.call(target,mergeFrom)
b
それを呼び出して、常にオブジェクトプロパティを使用する競合関数を渡します。
var result = merge(target,mergeFrom,function (a,b,prop) {
if (prop === null) return b
return b[prop]
})
3 つの配列と、値を最初の配列にプッシュする競合関数を渡して呼び出す
var mergedArr = merge({arr:[1]},{arr:[2]},{arr:[3]},function (a,b,prop) {
if (a[prop] != b[prop]) a.push(b[prop])
return a[prop]
})
JSBinの例を次に示します。
出力
例 1 -console.log(target)
{
"arr": [1, 5, 3, 6],
"as": "arguments",
"conflict": "target",
"more": "Objects",
"object": {
"another": "property",
"origin": "target"
},
"other": "unique",
"typeConflict": "primitive",
"unique": "a"
}
例 2 -console.log(result)
{
"arr": [3, 2, 7, 1],
"conflict": "mergeFrom",
"object": {
"another": "property",
"origin": "mergeFrom"
},
"other": "unique",
"typeConflict": ["object"],
"unique": "a"
}
例 3 -console.log(mergedArr)
{
"arr": [1, 2, 3]
}