Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie tiefe und flache Kopien von Arrays und Objekten

So implementieren Sie tiefe und flache Kopien von Arrays und Objekten

一个新手
一个新手Original
2017-10-09 10:04:531891Durchsuche

Prämisse: Der Unterschied zwischen primitiven Datentypen und Objekttypen beim Zuweisen von Werten

Die Datentypen von JavaScript sind in primitive Datentypen und Objekttypen unterteilt. Beide werden auf unterschiedliche Weise im Gedächtnis abgelegt, wodurch sich Unterschiede in der Zuordnung ergeben. Nehmen wir jeweils eine Kastanie

  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]

Aus der Kastanie oben ist ersichtlich: Wenn dem ursprünglichen Datentyp ein Wert zugewiesen wird, werden nach der Zuweisung die beiden Werte angegeben ​​sind einfach gleich, nicht Gegenseitiger Einfluss; Der Objekttyp gibt die Referenzadresse der Originaldaten an, sodass sich die alten und neuen Daten gegenseitig beeinflussen, da es sich im Wesentlichen um dasselbe Datenobjekt handelt , z als Array in Shangli

Was ist flache Kopie?

Wie der Name schon sagt, handelt es sich bei der flachen Kopie um eine oberflächliche Kopiermethode. Wenn der Attributwert ein Objekttyp ist, wird nur der Verweis auf die Objektdaten kopiert, was zur Folge hat Auch wenn alte und neue Daten nicht vollständig getrennt sind, wirken sie sich gegenseitig aus. Nehmen wir ein anderes Beispiel...


  //测试数据
  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}]

In der Kastanie ist Array2 ein flaches Kopierobjekt von Array1. Die Array-Elemente sind von primitiven Datentypen und haben keine Auswirkungen einander (array1[ 0]), aber array1[3] ist ein Objekttyp und beeinflusst sich weiterhin gegenseitig.

So implementieren Sie eine flache Kopie

  1. Array.concat() oder array.slice() in Shangli ist eine spezielle Implementierung einer flachen Kopie von Array-Weg.

  2. Wie kann ich es selbst umsetzen? Wäre es nicht ausreichend, jedes Attribut des Objekts/Arrays zu durchlaufen und es dann einem neuen Objekt zuzuweisen? Die folgende Implementierung

  //实现浅拷贝
  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
  }

  //测试

  var test = [1,'a',{name:'lei',age:18}];

  var copy = shallowCopy(test);
  console.log(copy[2].name);   //lei

  copy[2].name = 'zhang';
  console.log(test[2].name);   //zhang   原数据也被修改

Deep Copy und ihre Implementierung

Von Sie können im Grunde verstehen, dass eine tiefe Kopie eine „vollständige“ Kopie ist. Nach dem Kopieren sind die alten und neuen Daten vollständig getrennt und teilen sich nicht mehr die Attributwerte des Objekttyps sich gegenseitig beeinflussen.

Implementierungsmethode:

  1. Knifflige Methode JSON.parse(JSON.stringify(Obj))

var test = [1,'a',{name:'lei',age:18}];

var copy1 = JSON.parse(JSON.stringify(test));  //特殊方式

console.log(copy1);

copy1[2].name = 'zhang'
console.log(test);   //[1,'a',{name:'lei',age:18}]  未受到影响

 Hinweis: Diese Methode kann keine Objekte tief kopieren, deren Attributwerte Funktionen sind. Sie können es selbst versuchen

 2. Implementieren Sie Deep Copy

 Flache Kopie wurde durchgeführt Wenn man darüber nachdenkt, sollte das Ergebnis beim Zuweisen des Objekttyp-Attributwerts keine vollständige Trennung sein, daher müssen wir die Art und Weise des Kopierens des Objekttyp-Attributwerts ändern und erneut eine tiefe Kopie aufrufen Realisieren Sie die tiefe Kopie wie folgt:

//实现深拷贝
function deepCopy( target ){
  if(typeof target !== 'object') return ;
  //判断目标类型,来创建返回值
  var newObj = target instanceof Array ? [] : {};

  for(var item in target){
    //只复制元素自身的属性,不复制原型链上的
    if(target.hasOwnProperty(item)){
      newObj[item] = typeof target[item] == 'object' ? deepCopy(target[item]) : target[item]  //判断属性值类型    }
  }

  return newObj
}

//测试
var test = [1,'a',{name:'lei',age:18}];

var copy2 = deepCopy(test);
copy2[2].name = 'zhang'

console.log(test);  ////[1,'a',{name:'lei',age:18}]  未受到影响

Zusammenfassung

Stellen Sie sicher, dass Sie die Gründe für die flache Kopie verstehen: Beim Kopieren von Objekttypdaten werden die Referenzadresse und dieselben Daten kopiert Das Objekt wird weiterhin verwendet. Die Methode zum Implementieren einer tiefen Kopie besteht darin, die Attributwerte des Objekttyps rekursiv tief zu kopieren, um eine direkte Zuweisung zu vermeiden.

Das obige ist der detaillierte Inhalt vonSo implementieren Sie tiefe und flache Kopien von Arrays und Objekten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn