Contexte
J'ai une fonction qui prend un config
objet comme argument. Dans la fonction, j'ai aussi un default
objet. Chacun de ces objets contient des propriétés qui fonctionnent essentiellement comme des paramètres pour le reste du code dans la fonction. Afin d'éviter d'avoir à spécifier tous les paramètres de l' config
objet, j'utilise la extend
méthode de jQuery pour remplir un nouvel objet, settings
avec toutes les valeurs par défaut de l' default
objet si elles n'ont pas été spécifiées dans l' config
objet:
var config = {key1: value1};
var default = {key1: default1, key2: default2, key 3: default 3};
var settings = $.extend(default, config);
//resulting properties of settings:
settings = {key1: value1, key2: default2, key 3: default 3};
Problème
Cela fonctionne très bien, mais j'aimerais reproduire cette fonctionnalité sans avoir besoin de jQuery. Existe-t-il un moyen tout aussi élégant (ou proche de) de le faire avec du javascript ordinaire?
Edit: Justification non dupliquée
Cette question n'est pas un double de la question " Comment fusionner dynamiquement les propriétés de deux objets JavaScript? ". Alors que cette question veut simplement créer un objet qui contient toutes les clés et valeurs de deux objets séparés - je veux spécifiquement expliquer comment faire cela dans le cas où les deux objets partagent certaines mais pas toutes les clés et quel objet aura la priorité ( la valeur par défaut) pour l'objet résultant dans le cas où il y aurait des clés en double. Et plus précisément encore, je voulais aborder l'utilisation de la méthode de jQuery pour y parvenir et trouver un moyen alternatif de le faire sans jQuery. Bien que de nombreuses réponses aux deux questions se chevauchent, cela ne signifie pas que les questions elles-mêmes sont les mêmes.
la source
jQuery.isPlainObject
etjQuery.isFunction
Réponses:
Pour obtenir le résultat dans votre code, vous devez faire:
Gardez à l'esprit que la façon dont vous avez utilisé l'extension modifiera l'objet par défaut. Si vous ne le voulez pas, utilisez
Une solution plus robuste qui imite la fonctionnalité de jQuery serait la suivante:
la source
Vous pouvez utiliser Object.assign.
Il copie les valeurs de toutes les propriétés propres énumérables d'un ou plusieurs objets source vers un objet cible et renvoie l'objet cible.
Il fonctionne dans tous les navigateurs de bureau sauf IE (mais y compris Edge). Il a atténué le support mobile.
Voyez par vous-même ici: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
À propos de la copie profonde
Cependant, Object.assign n'a pas l'option profonde de la méthode extend de jQuery.
Remarque: vous pouvez généralement utiliser JSON pour un effet similaire
la source
Vous pouvez utiliser l' opérateur de diffusion ECMA 2018 dans les littéraux d'objet ...
Prise en charge de BabelJS pour les anciens navigateurs
la source
C'est mon approche légèrement différente avec la copie profonde que j'ai trouvée en essayant d'éliminer une dépendance jQuery. Il est principalement conçu pour être petit, il se peut donc qu'il n'ait pas toutes les fonctionnalités attendues. Doit être entièrement compatible ES5 (à partir de IE9 en raison de l'utilisation d' Object.keys ):
Vous pouvez vous demander ce que fait exactement la cinquième ligne ... Si obj2.key est un objet littéral (c'est-à-dire s'il ne s'agit pas d'un type ordinaire), nous appelons récursivement extend sur lui. Si une propriété avec ce nom n'existe pas encore dans obj1, nous l'initialisons d'abord à un objet vide. Sinon, nous définissons simplement obj1.key sur obj2.key.
Voici quelques-uns de mes tests mocha / chai qui devraient prouver que les cas courants fonctionnent ici:
Je serais heureux de recevoir des commentaires ou des commentaires sur cette mise en œuvre. Merci d'avance!
la source
Vous pouvez parcourir les propriétés de l'objet à l'aide de
for
statement.la source
a
. Bien que ce ne soit pas dans l'exemple,$.extend
fonctionne en fait de cette façon, en fusionnant toutes les propriétés de tous les objets.Je préfère ce code qui utilise mon forEachIn générique, et ne modifie pas le premier objet:
Si vous voulez vraiment fusionner des éléments dans le premier objet, vous pouvez faire:
la source
Cela m'aide beaucoup lorsque je développe avec du javascript pur.
la source
L'approche d'Ivan Kuckir peut également être adaptée pour créer un nouveau prototype d'objet:
la source