48 votes

Natif de façon à fusionner des objets en Javascript

Javascript, l'Objet n'a aucun natif opération de fusion. Si vous avez deux objets, dire

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

Et que vous souhaitez obtenir

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

Autant que je sache, vous avez pour itérer sur les objets. C'est-à-dire que vous décidez sur une fusion de gauche ou de fusionner droit de la stratégie et ensuite vous faites quelque chose comme (simplifié)

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

C'est très bien. Cependant, Javascript a l' call et prototype fonctionnalité. Par exemple, en tournant arguments en Array peut être fait avec

Array.prototype.slice.call(arguments)

Cette approche exploite existant en code natif, et donc, par conséquent, est moins sensible à la programmeur folie et doit courir plus vite qu'un non-natif de mise en œuvre.

La question

Est-il une astuce pour utiliser ce prototype/modèle d'appel sur peut-être l' Attribute ou Node de la traversée caractéristiques de la DOM, ou peut-être certains des génériques String fonctions afin d'en faire un objet natif de fusion?

Le code devrait ressembler à quelque chose comme ceci:

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

Et comme un résultat, vous obtenez un natif de fusion sans une traversée.

Une possible sous-optimale de la solution

Si vous pouviez utiliser le constructor de la propriété de l' Object puis de forcer un objet à posséder un constructeur d'un autre objet, puis exécutez new - dessus de l'objet composite, vous pouvez obtenir une fusion gratuitement. Mais je n'ai pas bien saisi toutes les implications de l' constructor fonction en javascript pour faire cet appel.

Lemme

La même question vaut pour Arrays. Un problème commun est d'être, par exemple 7 tableaux de nombres, puis essayer de trouver l'intersection de ces tableaux. C'est-à-dire les nombres qui existent dans tous les 7 tableaux.

Vous pourriez concat ensemble, puis faire un tri, puis une traversée, sûrement. Mais ce serait bien si il y a un générique se croisent niché quelque part que l'on peut contraindre un tableau à faire nativement.

Toutes les pensées?

edit:

Arriver à la moitié du chemin

Pour le tableau de problème, vous pouvez effectuer les opérations suivantes:

tableau.concat(a, b, c).sort().join(':') et puis utiliser certains délicate RegExp de la capture et de la répétition des motifs, afin de traverser. RegExp implémentations, si vous ne savez pas, fonctionner sur une très simple basée sur la pile de la machine virtuelle. Lorsque vous initialisez votre expression régulière qui est vraiment un programme qui sera compilé (RegExp.la compilation est obsolète méthode JS). Ensuite, le natif de passe sur la chaîne dans un blisteringly rapidement. Peut-être que vous pourriez exploiter que pour les membres de seuils et d'obtenir de meilleures performances...

Il continue à ne pas aller tout le chemin à travers.

25voto

Jakob Points 11155

Ma réponse à cette question sera décevant, mais encore:

pas de

La raison pour cela est simple: M. Resig de la mise en œuvre de la fusion (ou "étendre", comme on dit pour les objets) en jQuery est en train de faire une boucle, tout comme celui de votre question. Vous pouvez la regarder ici. Et j'ose dire que si John Resig n'a pas trouvé un astucieux construire-dans le moyen de le faire, puis les simples mortels de stackoverflow ne sera pas plus :)

2voto

Brian Donovan Points 3649

Pas que je sache, non. Aussi, vous aurez envie d'écrire votre méthode de fusion comme ceci:

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;
}

1voto

Ron Anon Points 11

Vous pouvez effectuer les opérations suivantes à l'aide de code JS 1.7, sans la nécessité d'un cadre. Voir l'exemple sur le violon (exemple prévu uniquement pour des objets simples - pas de complexe d'objets imbriqués)

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);

0voto

Informate.it Points 61

Aucun natif façons ECMA-Script, utilisez:

function merge(o1,o2) {
 if (typeof(o1)!=='object') o1={};
 if (typeof(o2)!=='object') o2={};
 for (var k in o2) {
 if (o1[k]!==undefined)
  alert ('Collision Error'); // TODO
 else
   o1[k]=o2[k];
 }
 return o1;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X