[英]Why does jQuery Extend Deep Copy not recursively copy an object?
[英]Why does jQuery Extend fail to recursively copy these two object literals?
我正在使用jQuery $ .extend方法對兩個對象進行遞歸合並,但是它沒有按我期望的那樣工作。 (此外:這些對象文字是CKEditor配置其工具欄所需的格式。)
預期結果:最大化,ShowBlocks和Source。
實際結果:最大化,顯示塊。
var obj1 = [
{ name: 'styles', items: ['Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] },
];
var obj2 = [
{ name: 'tools', items: ['Source'] }
];
var recursiveFail = $.extend(true, {}, obj1, obj2);
// Test result here....
alert(recursiveFail[2].items);
問題:為什么不添加“源”選項?
$.extend
不能那樣工作:它將對象的屬性從一個對象復制到另一個對象。 它無法識別“我看到此數組的這些對象中的'name'是相同的,所以我知道要合並'items'數組”這樣的事情。
您可能必須編寫自己的循環才能用obj2
擴展obj1
。
// Add 'Source' command to the tools group
for (var i = 0; i < obj1.length; i++) {
if (obj1[i].name === 'tools') {
obj1[i].items.push('Source');
break;
}
}
$.extend
不能以這種方式使用。
但是,您可以編寫自己的擴展/合並功能。 這是一個函數示例,該函數會將多個提供的數組中被認為相等(基於特定鍵的值)的每個對象合並在一起。
以下合並算法將覆蓋原始值並連接數組。 初始數組及其對象未修改。
如果只需要執行一次,那可能就太過分了,但是這是如何實現自己的封裝合並算法的一個示例。
function mergeOnKey(mergeKey) {
var mergedObjectsIndex = {},
mergedObjects = [],
arrays = Array.prototype.slice.call(arguments, 1),
i = 0,
arraysLen = arrays.length,
x, arrLen, arr, obj, k,
mergeVal, mergedObjIndex,
mergedObj, mergedVal;
for (; i < arraysLen ; i++) {
arr = arrays[i];
for (x = 0, arrLen = arr.length; x < arrLen; x++) {
obj = arr[x];
mergeVal = obj[mergeKey];
mergedObjIndex = mergedObjectsIndex[mergeVal];
if (typeof mergedObjIndex === 'undefined') {
mergedObjectsIndex[mergeVal] = mergedObjects.push($.extend({}, obj)) - 1;
continue;
}
mergedObj = mergedObjects[mergedObjIndex];
for (k in obj) {
if (!obj.hasOwnProperty(k) || k === mergeKey) continue;
if (Array.isArray(mergedVal = mergedObj[k])) mergedObj[k] = mergedVal.concat(obj[k]);
else mergedObj[k] = obj[k];
}
}
}
return mergedObjects;
}
然后,您可以像這樣使用它:
var obj1 = [
{ name: 'styles', items: ['Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] }
];
var obj2 = [
{ name: 'tools', items: ['Source'], test: 'test' }
];
var merged = mergeOnKey('name', obj1, obj2);
console.log(merged[2].items); //["Maximize", "ShowBlocks", "Source"]
您可以使用lodash庫中的 merge方法。 檢查以下答案:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.