Maison  >  Article  >  interface Web  >  Introduction détaillée à la copie profonde et à la copie superficielle en js (analyse de code)

Introduction détaillée à la copie profonde et à la copie superficielle en js (analyse de code)

不言
不言original
2018-08-14 11:25:28934parcourir

Le contenu de cet article est une introduction détaillée (analyse de code) sur la copie profonde et la copie superficielle en js. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Types de base et types de référence

Les types de données dans ECMAScript peuvent être divisés en deux types :

Basique Type : non défini, null, booléen, chaîne, nombre, symbole
Type de référence : objet, tableau, date, fonction, RegExp, etc.

Différent types Méthode de stockage :

Type de base  : La valeur du type de base occupe une taille fixe en mémoire et est stockée dans la mémoire de la pile
Type de référence  : Référence type La valeur est un objet, qui est stocké dans la mémoire tas, tandis que la mémoire pile stocke l'identifiant de variable de l'objet et l'adresse de stockage de l'objet dans la mémoire tas

Différents types de copie méthodes :

Type de base

  • Type de base : copier une valeur de type de base d'une variable vers une autre nouvelle variable créera une copie de la valeur. Et copiez la copie dans la nouvelle variable

let foo = 1;
let bar = foo;
console.log(foo === bar); // -> true

// 修改foo变量的值并不会影响bar变量的值
let foo = 233;
console.log(foo); // -> 233
console.log(bar); // -> 1
  • Type de référence : Copiez la valeur du type de référence d'une variable vers une autre nouvelle variable. . En fait, ce qui est copié est Pointer, finalement les deux variables pointent vers le même objet

let foo = {
  name: 'leeper',
  age: 20
}
let bar = foo;
console.log(foo === bar); // -> true

// 改变foo变量的值会影响bar变量的值
foo.age = 19;
console.log(foo); // -> {name: 'leeper', age: 19}
console.log(bar); // -> {name: 'leeper', age: 19}

Copie profonde et copie superficielle

  • . Copie superficielle : Seules les références sont copiées, et les opérations entre elles s'affecteront

  • Copie profonde : Réallouer de la mémoire dans le tas, des adresses différentes, les mêmes valeurs, ne s'affectent pas

Copie superficielle

Donnez un exemple ()

  var me = {
      name: 'zjj',
      age: 19,
      address: {
          home: 'tianjin'
      }
  };
  
  var me_1 = {
      m_token: 'new'
  };
  
  
  function extend(p, c){
      var c = c || {};
      
      for(var i in p) {
          c[i] = p[i];
      }
  }
  extend(me,me_1);

Introduction détaillée à la copie profonde et à la copie superficielle en js (analyse de code)

Copie approfondie

  var me = {
      name: 'zjj',
      age: 19,
      address: {
          home: 'tianjin'
      }
  };
  
  var me_1 = {
      m_token: 'new'
  };
  
  
  function extend(p, c){
      var c = c || {};
      
      for(var i in p) {
          c[i] = p[i];
      }
  }


  function extendDeeply(p, c) {
    var c = c || {};
      
      for(var i in p) {
        if(typeof p[i] === 'object') {
          // 引用类型需要递归实现深拷贝
          c[i] = (p[i].constructor === Array ) ? [] : {}
          extendDeeply(p[i], c[i]);
        } else {
          // 非引用类型直接复制即可
          c[i] = p[i];
        } 
      }
  }
  extendDeeply(me,me_1);

Introduction détaillée à la copie profonde et à la copie superficielle en js (analyse de code)

  • JSON .parse() et JSON.stringify()

JSON.stringify() : sérialiser un objet js dans une chaîne JSON
JSON.parse() : Convertir JSON La chaîne est désérialisée en objet js
let obj = {
  name: 'leeper',
  age: 20,
  friend: {
    name: 'lee',
    age: 19
  }
};
let copyObj = JSON.parse(JSON.stringify(obj));
obj.name = 'Sandman';
obj.friend.name = 'Jerry';
console.log(obj);
// -> {name: "Sandman", age: 20, friend: {age: 19,name: 'Jerry'}}
console.log(copyObj);
// -> {name: "leeper", age: 20, friend: {age: 19,name: 'lee'}}

En résumé, JSON.parse() et JSON.stringify() sont des copies complètes complètes.

Implémentation pratique de la copie profonde Utilisez [récursion] pour implémenter la copie complète d'un objet ou d'un tableau. Idée récursive : parcourez toutes les valeurs de type référence dans l'attribut jusqu'à ce qu'il s'agisse d'une valeur de type de base.

// 深拷贝
function deepCopy(obj) {
  if (!obj && typeof obj !== 'object') {
    throw new Error('error arguments');
  }
  // const targetObj = obj.constructor === Array ? [] : {};
  const targetObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    
    //只对对象自有属性进行拷贝
    if (obj.hasOwnProperty(key)) {
      if (obj[key] && typeof obj[key] === 'object') {
        targetObj[key] = deepCopy(obj[key]);
      } else {
        targetObj[key] = obj[key];
      }
    }
  }
  return targetObj;
}

La méthode de copie est en fait une méthode d'héritage. Bien sûr, il existe d'autres méthodes d'héritage !

Recommandations associées :

Une brève introduction à la copie superficielle et à la copie profonde en js et à leurs méthodes de mise en œuvre

Quel est le concept de mécanisme d'exécution js ? Méthode d'implémentation du mécanisme d'exécution js

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!

Déclaration:
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