Maison  >  Article  >  interface Web  >  Explication détaillée des copies profondes et superficielles des tableaux et objets js

Explication détaillée des copies profondes et superficielles des tableaux et objets js

小云云
小云云original
2018-02-01 09:03:401381parcourir

Cet article présente principalement la copie profonde et superficielle des tableaux et des objets en js. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer. J'espère que Meng pourra vous aider.

Prémisse : La différence entre les types de données primitifs et les types d'objets lors de l'attribution de valeurs.

Les types de données JavaScript sont divisés en types de données primitifs et types d'objets. Les deux sont stockés de différentes manières en mémoire, ce qui entraîne des différences dans leur affectation. Prenons respectivement une châtaigne


var x = 1;
 var y = x; //y获得了和x同样的值
 y = 2;
 console.log(x); // 1

 var m = [1,2]; //m存放的是指向[1,2]这个数组对象的引用地址
 var n = m; //n也获得 [1,2]数组对象的引用地址
 n[0] = 3;
 console.log(m); //[3,2]

Cela peut être vu sur la châtaigne ci-dessus : lorsque le type de données d'origine est attribué, la valeur réelle des données est donnée après l'affectation. , les deux sont juste Les valeurs sont exactement les mêmes et ne s'affecteront pas ; le type d'objet donne l'adresse de référence des données d'origine, donc les anciennes et les nouvelles données s'affecteront, car ce sont essentiellement les mêmes données. objet, comme le tableau dans Shangli

Qu'est-ce qu'une copie superficielle ?

Comme son nom l'indique, la copie superficielle est une méthode de copie superficielle ; lorsque la valeur de l'attribut est un type d'objet, seule la référence aux données de l'objet est copiée, ce qui donne l'ancien et le nouveau. les données ne sont pas complètement séparées et elles interagiront également les unes avec les autres. Prenons un autre exemple...


//测试数据
var array1 = ['a',1,true,{name:'lei',age:18}];
 
//concat() slice() 实现浅拷贝
var array2 = array1.concat()
 
//修改拷贝后的数据
array2[0] = 'b';      //array1[0]是原始数据类型 所以是直接赋值的
array2[3].name = 'zhang';  //array1[3]是对象数据类型 所以拷贝的是对象的引用,其实还是和原数组使用同一对象
 
console.log(array1);  // ['a',1,true,{name:'zhang',age:18}]

Dans le châtaignier, array2 est une copie superficielle de array1. Les éléments du tableau sont de types de données primitifs et n'affecteront pas. les uns les autres (array1[ 0]), mais array1[3] est un type d'objet et s'affectera toujours.

Comment implémenter une copie superficielle

Array.concat() ou array.slice() dans Shangli est une manière spéciale d'implémenter une copie superficielle d'un tableau.

Comment le mettre en œuvre soi-même ? Ne suffirait-il pas de parcourir chaque attribut de l'objet/tableau puis de l'attribuer à un nouvel objet ? Comme suit, implémentez


 //实现浅拷贝
 function shallowCopy( target ){
  if(typeof target !== 'object') return ;
  //判断目标类型,来创建返回值
  var newObj = target instanceof Array ? [] : {};
 
  for(var item in target){
   //只复制元素自身的属性,不复制原型链上的
   if(target.hasOwnProperty(item)){
    newObj[item] = target[item]
   }
  }
 
  return newObj
 }</strong>
 
 //测试
 
 var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}];
 
 var copy = shallowCopy(test);
 console.log(copy[2].name);  //lei
 
 copy[2].name = &#39;zhang&#39;;
 console.log(test[2].name);  //zhang  原数据也被修改

copie profonde et sa mise en œuvre

On peut essentiellement comprendre à partir de l'explication de la copie superficielle que la copie profonde est une copie « complète » après la copie, les anciennes et les nouvelles données sont complètement. séparés et ne partagent plus les valeurs d'attribut du type d'objet et ne s'affecteront pas.

Méthode d'implémentation :

Méthode délicate JSON.parse(JSON.stringify(Obj))


var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}]; 
var copy1 = JSON.parse(JSON.stringify(test)); //特殊方式 
console.log(copy1); 
copy1[2].name = &#39;zhang&#39;
console.log(test);  //[1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}] 未受到影响

Remarque : Cette méthode ne peut pas copier en profondeur les objets dont les valeurs d'attribut sont des fonctions. Vous pouvez l'essayer vous-même

2 Implémenter la copie profonde

Nous avons déjà implémenté la copie superficielle. Pensez-y. Lors de l'attribution de valeurs aux attributs de type d'objet, le résultat est une séparation incomplète. Par conséquent, nous devons modifier la façon de copier les valeurs d'attribut de type d'objet et appeler à nouveau une copie approfondie. comme suit :


//实现深拷贝
function deepCopy( target ){
 if(typeof target !== &#39;object&#39;) return ;
 //判断目标类型,来创建返回值
 var newObj = target instanceof Array ? [] : {};
 
 for(var item in target){
  //只复制元素自身的属性,不复制原型链上的
  if(target.hasOwnProperty(item)){
   newObj[item] = <strong>typeof target[item] == &#39;object&#39; ? deepCopy(target[item]) : target[item] //判断属性值类型
</strong>  }
 }
 
 return newObj
}
 
//测试
var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}];
 
var copy2 = deepCopy(test);
copy2[2].name = &#39;zhang&#39;
 
console.log(test); ////[1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}] 未受到影响

Résumé

Assurez-vous de comprendre la cause de la copie superficielle : lors de la copie d'un objet tapez les données, l'adresse de référence est copiée, en utilisant C'est toujours le même objet de données ; donc la façon d'implémenter la copie complète est de copier en profondeur de manière récursive la valeur de l'attribut du type d'objet pour éviter l'affectation directe.

Recommandations associées :

Analyse des exemples de copie superficielle et de copie profonde $.extend de JQuery

Que sont la copie profonde et la copie superficielle js Et sa méthode de mise en œuvre

Réaliser une copie profonde et une copie superficielle dans jquery

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