JavaScript 对象合并
Posted 忧郁的蛋~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 对象合并相关的知识,希望对你有一定的参考价值。
javascript 中有多种方法可以合并对象。
1、使用 Object.assign()
方法:
它可以将一个或多个对象的属性复制到目标对象中。例如:
const obj1 = a: 1, b: 2 ;
const obj2 = b: 3, c: 4 ;
const obj3 = Object.assign(, obj1, obj2);
console.log(obj3); // a: 1, b: 3, c: 4
这里我们使用空对象()作为第一个参数,避免直接修改第一个对象。
2、使用解构赋值语法:
这种方法会在合并对象时保留键值相同的对象的属性,例如:
const obj1 = a: 1, b: 2 ;
const obj2 = b: 3, c: 4 ;
const obj3 = ...obj1, ...obj2 ;
console.log(obj3); // a: 1, b: 3, c: 4
这里使用了扩展运算符,可以将一个对象的属性解构到另一个对象中。
3、使用 Lodash 中的 merge() 方法:
const obj1 = a: 1, b: 2 ;
const obj2 = b: 3, c: 4 ;
const obj3 = _.merge(obj1, obj2);
console.log(obj3); // a: 1, b: 3, c: 4
4、for-in 循环 + 手动赋值:
const obj1 = a: 1, b: 2 ;
const obj2 = b: 3, c: 4 ;
const obj3 = ;
for (const key in obj1)
obj3[key] = obj1[key];
for (const key in obj2)
obj3[key] = obj2[key];
console.log(obj3); // a: 1, b: 3, c: 4
5、使用 Object.keys() 和 Array.forEach() 方法:
const obj1 = a: 1, b: 2 ;
const obj2 = b: 3, c: 4 ;
const obj3 = ;
Object.keys(obj1).forEach(key =>
obj3[key] = obj1[key];
);
Object.keys(obj2).forEach(key =>
obj3[key] = obj2[key];
);
console.log(obj3); // a: 1, b: 3, c: 4
最后需要提醒的是,在合并对象时如果键值相同的对象属性类型不同,例如一个为字符串类型,一个为数值类型,会覆盖之前的属性,因此需要根据项目需求做出相应的处理。
此外,如果需要对合并对象的属性进行特殊处理,例如合并对象的属性值是一个数组,需要合并成一个新数组,可以使用 Array.concat() 方法。
const obj1 = a: [1, 2] ;
const obj2 = a: [3, 4] ;
const obj3 = Object.assign(, obj1,
a: obj1.a.concat(obj2.a)
);
console.log(obj3); // a: [1, 2, 3, 4]
或者使用扩展运算符
const obj1 = a: [1, 2] ;
const obj2 = a: [3, 4] ;
const obj3 = ...obj1, a: [...obj1.a, ...obj2.a]
console.log(obj3); // a: [1, 2, 3, 4]
此外,如果需要对合并对象的属性值进行进一步的处理,如去重、排序等,可以使用 Array.filter()、Array.sort() 等方法。
在 JavaScript 中合并两个对象(NodeList)数组
【中文标题】在 JavaScript 中合并两个对象(NodeList)数组【英文标题】:Merging two object (NodeList) arrays in JavaScript 【发布时间】:2013-01-17 21:16:52 【问题描述】:我正在尝试合并两个对象数组,以便验证表单。在这种情况下,通常的 concat 方法似乎不起作用。 Concat 适用于普通的数值和字符串数组,但不适用于对象数组。 var allTags = allInputs.concat(allSelects);
行不行。
var allInputs = document.getElementsByTagName("input");
alert("Inputs: " + allInputs.length);
var allSelects = document.getElementsByTagName("select");
alert("Selects: " + allSelects.length);
var allTags = allInputs.concat(allSelects);
alert("allTags: " + allTags.length);
【问题讨论】:
这不是数组,它的数组像对象(NodeList) 其实就是一个NodeList,所以没有concat方法。 【参考方案1】:Concat 适用于普通数值和字符串数组,但不适用于对象数组。
实际上是这样,但是NodeList
实例没有concat
方法,并且Array#concat
没有办法识别您想要展平这些(因为它们不是数组)。
但它仍然很容易做到(不过,请参阅下面的警告)。更改此行:
var allTags = allInputs.concat(allSelects);
到
var allTags = [];
allTags.push.apply(allTags, allInputs);
allTags.push.apply(allTags, allSelects);
Live Example | Source
这通过使用一点技巧来工作:Array#push
接受可变数量的元素添加到数组中,Function#apply
使用给定的 this
值调用函数(在我们的例子中,@987654335 @) 和任何类似数组的对象作为要传递给它的参数。由于NodeList
实例是类似数组的,push
很乐意将列表的所有元素推送到数组中。
Function#apply
的这种行为(不需要第二个参数真的是一个数组)在规范中非常明确定义,并且在现代浏览器中得到很好的支持。
遗憾的是,IE6 和 7 不支持上述内容(我认为它专门使用主机对象——NodeLists
——作为Function#apply
的第二个参数),但是我们不应该支持它们,要么。 :-) IE8 也没有,这更有问题。 IE9 对此很满意。
如果您需要支持 IE8 及更早版本,可悲的是,我认为您会遇到一个无聊的旧循环:
var allInputs = document.getElementsByTagName('input');
var allSelects = document.getElementsByTagName('select');
var allTags = [];
appendAll(allTags, allInputs);
appendAll(allTags, allSelects);
function appendAll(dest, src)
var n;
for (n = 0; n < src.length; ++n)
dest.push(src[n]);
return dest;
Live Example | Source
这确实适用于 IE8 及更早版本(以及其他)。
【讨论】:
@user2035797:不用担心,我现在还添加了一个适用于 IE8 及更早版本的示例。【参考方案2】:document.get[something]
返回一个NodeList,它看起来与Array 非常相似,但有许多与众不同的特点,其中两个是:
如果您在将 NodeList 转换为实际数组时没有任何问题,您可以执行以下操作来达到您想要的效果:
var allInputs = document.getElementsByTagName("input")
, allSelects = document.getElementsByTagName("select")
;//nodeLists
var inputList = makeArray(allInputs)
, selectList = makeArray(allSelects)
;//nodeArrays
var combined = inputList.concat(selectList);
function makeArray(list)
return Array.prototype.slice.call(list);
您将失去原始 NodeList 的所有行为,包括它能够实时更新以反映对 DOM 的更改,但我的猜测是,这不是一个真正的问题。
【讨论】:
请注意,就像我在回答的第一部分中给出的类似解决方案一样,这在 IE8 或更早版本中不起作用。 (在这里试试:jsbin.com/iledok/1)sigh 至少 IE9 还不错。所以对于 IE8 及更早版本,需要一个无聊的旧循环。【参考方案3】:您正在处理的是HTMLCollection
s,它们是实时集合(即,当您将节点添加到 DOM 时,它会自动添加到集合中。
遗憾的是,它没有concat
方法……这是有原因的。您需要做的是将其转换为数组,从而失去其实时行为:
var allInputsArray = [].slice.call(allInputs),
allSelectsArray = [].slice.call(allSelects),
allFields = allInputsArray.concat(allSelectsArray);
【讨论】:
【参考方案4】:我找到了一种按 dom 对象在页面或表单中出现的顺序收集它们的简单方法。 首先,在对象上创建一个虚拟类样式“reqd”,然后使用以下内容按照它们在页面上出现的顺序创建一个列表。只需将类添加到您希望收集的任何对象。
var allTags = document.querySelectorAll("input.reqd, select.reqd");
【讨论】:
【参考方案5】:查看过 underscore.js 吗?你可以这样做
var allSelectsAndInputs = _.union(_.values(document.getElementsByTagName("input")),_.values(document.getElementsByTagName("select")));
欲了解更多信息,请参阅:http://underscorejs.org/#extend
该函数适用于对象,但在此设置中有效。
【讨论】:
实际上,我正在玩它……它似乎有点不对劲。待命。 如果您喜欢,请考虑对我的回答进行投票。以上是关于JavaScript 对象合并的主要内容,如果未能解决你的问题,请参考以下文章