首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Javascript中合并对象的本机方法

在Javascript中合并对象的本机方法
EN

Stack Overflow用户
提问于 2011-01-20 05:10:51
回答 6查看 22.8K关注 0票数 48

Javascript的对象没有任何本机合并操作。如果你有两个对象,比如说

{a:1, b:2}
{c:3, d:4}

并且想要得到

{a:1, b:2, c:3, d:4}

据我所知,您必须遍历对象。也就是说,您决定使用merge left或merge right策略,然后执行以下操作(简化)

for (key in object2) {
  object1[key] = object2[key];
}

这很好。但是,Javascript具有callprototype功能。例如,可以使用以下命令将arguments转换为Array

Array.prototype.slice.call(arguments)

这种方法利用了现有的本机代码,因此不容易受到程序员愚蠢行为的影响,并且应该比非本机实现运行得更快。

问题是

在DOM的AttributeNode遍历特性上,或者在一些通用的String函数上使用这种原型/调用模式,以便进行本机对象合并,有什么技巧吗?

代码将如下所示:

var merged = somethingrandom.obscuremethod.call(object1, object2)

因此,您可以在没有遍历的情况下获得本机合并。

一个可能的、次优的解决方案

如果您可以使用Objectconstructor属性,然后强制一个对象具有另一个对象的构造函数,然后在复合对象上运行new,则可以免费获得合并。但是我不能很好地理解javascript中constructor特性的全部含义,无法做出这样的调用。

引理

同样的问题也适用于Arrays。一个常见的问题是,假设有7个数字数组,然后尝试找出这些数组的交集。也就是说,哪些数字在所有7个数组中都存在。

您可以将它们连接在一起,然后进行排序,然后进行遍历。但如果有一个通用的交集隐藏在某个地方,我们可以强制一个数组在本地执行,那就太好了。

有什么想法吗?

编辑:

半途而废

对于数组问题,您可以执行以下操作:

array.concat(a,b,c).sort().join(':'),然后使用一些棘手的RegExp捕获和重复模式来遍历。如果您不了解RegExp实现,可以在一个非常简单的基于堆栈的虚拟机上运行。当您初始化正则表达式时,这实际上是一个需要编译的程序(RegExp.compile是一个已弃用的JS方法)。然后,本机以极快的速度遍历字符串。也许你可以利用这一点作为会员阈值,并获得更好的性能……

尽管如此,它仍然没有走完所有的路。

EN

回答 6

Stack Overflow用户

发布于 2015-11-07 01:37:51

百万美元的问题!我尝试过很多种方法,上面描述的循环方法似乎总是最脏的。ES6的Object.setPrototypeOf()允许你将一个“属性覆盖”对象委托给一个“默认属性”对象,这很大程度上实现了你想要做的事情,但是使用Object.setPrototypeOf()会带来一些严重的影响,比如禁用浏览器对整个脚本的编译器优化。

此外,在循环解决方案和Object.setPrototypeOf()解决方案中,您都会遇到“属性覆盖”对象可以改变“默认属性”对象的情况:

defaultObj = {
    a: [1, 2]
}
...
overrideObj = {
    b: 3
}
Object.setPrototypeOf(overrideObj, defaultObj);
console.log(overrideObj); // {a: [1, 2], b: 3}
// Great!
...
overrideObj.a.push(4);
console.log(defaultObj); // {a: [1, 2, 4]}
// Uh-oh.

您可能认为这不是问题,但假设您正在使用此对象作为第三方库的配置。您现在将默认对象和其中引用的所有内容的控制权交给第三方lib。

更好的解决方案可能是使用JSON.stringify和JSON.parse来复制和组合对象。下面是示例的要点:https://gist.github.com/spikesagal/6f7822466887f19b9c65

HTH

票数 3
EN

Stack Overflow用户

发布于 2011-01-20 05:17:02

据我所知没有。此外,您还需要像这样编写merge方法:

function mergeInto(o1, o2) {
  if (o1 == null || o2 == null)
    return o1;

  for (var key in o2)
    if (o2.hasOwnProperty(key))
      o1[key] = o2[key];

  return o1;
}
票数 2
EN

Stack Overflow用户

发布于 2013-08-15 09:45:34

您可以使用原生JS 1.7执行以下操作,而不需要框架。参见fiddle上的示例(示例仅适用于简单对象-不适用于复杂的嵌套对象)

var obj1 = {a: "a", b: "b"};
var obj2 = {c: "c", d: "d"};

// The magic: ugly but works perfectly
var value = (JSON.stringify(obj1).concat(JSON.stringify(obj2))).replace("}{", ",");

document.getElementById("lbl1").setAttribute("value", value);

// back to object
var obj3 = JSON.parse(value);
document.getElementById("lbl2").setAttribute("value", obj3.a + " " + obj3.b + " " + obj3.c + " " + obj3.d);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4740806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档