Maison > interface Web > js tutoriel > Comment implémenter la fonction de fusion d'objets

Comment implémenter la fonction de fusion d'objets

一个新手
Libérer: 2017-10-12 10:16:49
original
2653 Les gens l'ont consulté

Avant-propos

Le $.extend() dans jQuery est une fonction d'outil fréquemment utilisée, principalement utilisée pour fusionner des paramètres (objets). L'utilisation spécifique ne sera pas décrite ici. Vous pouvez contrôler ou non. le processus de fusion est effectué en passant des paramètres.Utilisez une copie profonde ; la nouvelle méthode Object.assign() dans ES2015 peut également réaliser une fusion d'objets, mais une copie superficielle est utilisée pendant le processus de fusion ; cet article fait référence au code source de la méthode d'extension de jQuery ; pour implémenter la fusion d'objets par lui-même, c'est-à-dire copier les attributs de plusieurs objets vers l'objet cible, s'il y a les mêmes attributs, les objets suivants écraseront les précédents.

Réaliser la fusion d'objets grâce à une copie superficielle

Un article de blog précédent a spécifiquement présenté la copie profonde et superficielle des objets et des tableaux. Si vous ne comprenez pas, veuillez lire ici. Regardons d'abord l'implémentation puis expliquons


    function extend() {  //extend 浅拷贝实现
      var name,options,copy,
          length = arguments.length,
          i = 1,
          target = arguments[0] || {};  //取目标对象
      
    if([&#39;object&#39;,&#39;function&#39;].indexOf(typeof target) < 0){
        target = {};
      }    

      for(;i<length;i++){

        options = arguments[i]        
        if(options != null){  //排除空参数的情况 extend({},,)

          for(name in options){   //遍历对象 赋值
            copy = options[name];            
            if (copy !== undefined) {
              target[name] = copy;
            }
          }
        }
      }      return target  
    }   //测试数据 
    var test1 = {
      a : 1,
      b : {
        c : 2,
        d : 3
      },
      e : [1,&#39;a&#39;]
    },
    test2 = {
      b : {
        c : 4,
        d : 5,
        f : 6
      },
      e : [1,&#39;a&#39;],
      g : 7
    }    var test = extend({},test1,test2);
    console.log(test.b.d);   //5
    test2.b.d = &#39;x&#39;;  //修改test2
    console.log(test.b.d);  // &#39;x&#39;   test随之修改
Copier après la connexion

L'idée est la suivante :

1. Par défaut, le premier paramètre est pris comme l'objet cible. Si le premier paramètre n'est pas de type de données Objet, alors attribuez la valeur à un objet vide

2. Parcourez les paramètres restants (objet source) et copiez les propriétés de l'objet source dans l'objet cible. .

3. Renvoyez l'objet cible comme résultat fusionné

Dans la deuxième étape, les valeurs d'attribut de l'objet source ne sont pas jugées. Toutes sont attribuées à l'aide de '=', Ainsi, lorsque l'objet source Lorsque la valeur d'attribut est un attribut d'objet, seule la valeur de référence est copiée, qui est une copie superficielle. D'après les résultats du test, on peut voir que les valeurs d'attribut de l'attribut b de test et test2. utilisent le même objet et s’influenceront mutuellement. Après avoir su cela, vous devriez également avoir des idées sur la façon de mettre en œuvre la copie approfondie lors de la fusion.

Méthode de copie approfondie pour réaliser la fusion d'objets

Lors de la copie de la valeur de l'attribut de l'objet source, vous devez déterminer le type de la valeur. S'il s'agit d'un type de données d'objet, appelez la fonction d'extension de manière récursive. . Ensuite, vous pouvez pratiquer la fusion d'objets en mode copie profonde, et la mise en œuvre est la suivante :


    function extend() {  //extend 深拷贝实现
      var name,options,src,copy,
          deep = false,  //是否深拷贝 默认为false
          length = arguments.length,
          i = 1,
          target = arguments[0] || {};      //如果第一个参数为boolean类型,赋值给deep
      if(typeof target  == &#39;boolean&#39;){
        deep = arguments[0];
        target = arguments[i] || {}; //目标对象顺延
        i++;
      }      //如果target不是对象数据类型的话  target赋值为 {}
      if([&#39;object&#39;,&#39;function&#39;].indexOf(typeof target) < 0){
        target = {};
      }      for(;i<length;i++){

        options = arguments[i];        
        if(options != null){          
        for(name in options){

            copy = options[name];
            src = target[name];            
            if(target === copy){  //避免重复循环
              continue;
            }            if(deep && copy && (typeof copy == &#39;object&#39;)){ // 类型判断
              src = Object.prototype.toString.call(copy) == &#39;[object Array]&#39; ? [] : {};  //区分数组和‘对象’
              target[name] = extend(deep,src,copy);
            }else {              
            if (copy !== undefined) {

                target[name] = copy;
              }
            }
          }
        }
      }      return target
    }
Copier après la connexion

1. Jugement des paramètres, si le premier paramètre est de type booléen, il est pris pour contrôler si les paramètres de copie profonde, deep, sont faux par défaut ;en même temps, l'élément cible sera le deuxième paramètre

 2. Lors de la copie de la valeur de l'attribut, vous devez déterminer le type du paramètre deep et valeur de l'attribut ; si deep est vrai et la valeur de l'attribut S'il s'agit d'un type d'objet, appelez la fonction extend de manière récursive, sinon attribuez directement la valeur

3. Il faut distinguer les tableaux et « objets » pour attribuer différentes valeurs initiales aux propriétés de l'objet cible. S'ils sont tous {}, la valeur d'attribut du type tableau copiée dans l'élément cible deviendra {'0':xx, '1': xx...}

Conclusion

Toujours Ils utilisent tous directement $.extend(). C'est facile à utiliser mais je ne suis pas très clair sur l'implémentation. Je* ne suis peut-être pas rigoureux dans l'implémentation, mais je pense que la récolte est bonne.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal