Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erklärung von Javascript Deep Copy (deepClone)

Detaillierte Erklärung von Javascript Deep Copy (deepClone)

高洛峰
高洛峰Original
2017-01-03 15:59:291071Durchsuche

Javascript Deep Copy ist ein Problem, auf das Anfänger und sogar erfahrene Entwickler häufig stoßen und das JavaScript Deep Copy nicht gut verstehen kann.

Deep Copy (deepClone)?

Das Gegenteil von Deep Copy ist Shallow Copy. Viele Anfänger sind sehr verwirrt, wenn sie mit diesem Konzept in Berührung kommen.

Warum Deep Copy verwenden?

In vielen Fällen müssen wir einer Variablen einen Wert zuweisen und der Speicheradresse einen Wert zuweisen. Bei der Zuweisung eines Referenzwerttyps teilt sich dieser jedoch nur einen Speicherbereich, was zur Folge hat Zuweisung bleibt erhalten.

Sehen Sie sich ein konkretes Beispiel an

// 给test赋值了一个对象
var test = {
  a: 'a',
  b: 'b'
};
 
// 将test赋值给test2
// 此时test和test2是共享了同一块内存对象,这也就是浅拷贝
var test2 = test;
 
test2.a = 'a2';
 
test.a === 'a2'// 为true

Abbildung:


Jetzt können Sie leicht verstehen, warum sich Referenzwerttypdaten gegenseitig beeinflussen.

Um

zu implementieren, müssen Sie über den numerischen Typ von JavaScript sprechen, um eine Deep-Copy-Funktion zu implementieren.

Javascript-Typ beurteilen

Es gibt die folgenden Grundtypen in Javascript

Typbeschreibung
undefiniert Der undefinierte Typ hat nur einen Wert, undefiniert, nämlich Wenn der Variablen kein Wert zugewiesen ist, hat der Wert vom Typ
null null auch nur einen Wert null, der eine leere Objektreferenz ist
Boolean Boolean hat zwei Werte true und false
String Stellt Text dar information
Number Es stellt numerische Informationen dar
Object Es ist eine ungeordnete Sammlung einer Reihe von Attributen, einschließlich Funktion und Array Array
Mithilfe von typeof ist es unmöglich, Funktion und Array zu beurteilen Hier kommt die Methode zum Einsatz.
[Standardmäßig erbt jedes Objekt die toString()-Methode von Object. Wenn diese Methode nicht durch die gleichnamige Methode auf dem Objekt selbst oder einem näheren oberen Prototyp überschrieben (geschattet) wird, wird dies von der toString()-Methode des Objekts übernommen Geben Sie „[Objekttyp]“ zurück, wobei der Zeichenfolgentyp einen Objekttyp darstellt][1]

function type(obj) {
  var toString = Object.prototype.toString;
  var map = {
    '[object Boolean]' : 'boolean', 
    '[object Number]'  : 'number', 
    '[object String]'  : 'string', 
    '[object Function]' : 'function', 
    '[object Array]'  : 'array', 
    '[object Date]'   : 'date', 
    '[object RegExp]'  : 'regExp', 
    '[object Undefined]': 'undefined',
    '[object Null]'   : 'null', 
    '[object Object]'  : 'object'
  };
  return map[toString.call(obj)];
}

implementiert deepClone

für Nicht-Werte von Referenzwerttypen werden direkt zugewiesen, während Referenzwerttypen (Objekt) erneut durchlaufen und rekursiv zugewiesen werden müssen.

function deepClone(data) {
  var t = type(data), o, i, ni;
   
  if(t === 'array') {
    o = [];
  }else if( t === 'object') {
    o = {};
  }else {
    return data;
  }
   
  if(t === 'array') {
    for (i = 0, ni = data.length; i < ni; i++) {
      o.push(deepClone(data[i]));
    }
    return o;
  }else if( t === &#39;object&#39;) {
    for( i in data) {
      o[i] = deepClone(data[i]);
    }
    return o;
  }
}

Hier gibt es etwas, auf das Sie achten sollten. Für den Funktionstyp weist der Blogger hier den Wert direkt zu oder teilt einen Speicherwert. Dies liegt daran, dass es bei der Funktion eher darum geht, bestimmte Funktionen abzuschließen, einen Eingabewert und einen Rückgabewert zu haben, und für das übergeordnete Unternehmen eher darum geht, Geschäftsfunktionen abzuschließen, und es keine Notwendigkeit gibt, die Funktion tatsächlich tief zu kopieren.

Aber wie kopiert man den Funktionstyp?

Tatsächlich dachte der Blogger nur daran, new zu verwenden, um es zu bedienen, aber die Funktion wird einmal ausgeführt. Ich kann mir nicht vorstellen, wie die Ausführungsergebnisse aussehen werden! o(╯□╰)o! Ich habe noch keine weiteren guten Ideen, daher ist jede Anregung willkommen!

Zu diesem Zeitpunkt ist Deep Copy fast implementiert. Glaubt irgendjemand, dass Shallow Copy noch nicht implementiert ist?

Flache Kopie?

Für flache Kopien kann es so verstanden werden, dass nur ein gemeinsamer Speicherbereich betrieben wird! Hier besteht Gefahr! (.﹏.*)

Wenn Sie diese gemeinsam genutzten Daten direkt und unkontrolliert verwalten, treten häufig Datenanomalien auf und werden von anderen Teilen geändert. Daher sollten Sie die Datenquelle nicht direkt bedienen, sondern einige Methoden für die Datenquelle kapseln, um CURD-Operationen für die Daten auszuführen.

Hier ist es wahrscheinlich fast geschafft, aber als Frontend muss nicht nur JavaScript selbst berücksichtigt werden, sondern auch DOM, Browser usw.

Elementtyp

Sehen Sie sich den folgenden Code an. Was wird zurückgegeben?

Object.prototype.toString.call(document.getElementsByTagName('div')[0])

Die Antwort ist [object HTMLDivElement]

Manchmal speichern Wenn Sie versehentlich eine tiefe Kopie des DOM-Elements durchführen, kann die obige Funktion für tiefes Kopieren das Elementelement nicht beurteilen. Um das Elementelement zu beurteilen, verwenden Sie zum Beurteilen die Instanz von. Denn für verschiedene Tags gibt tostring den Konstruktor zurück, der den verschiedenen Tags entspricht.

function type(obj) {
  var toString = Object.prototype.toString;
  var map = {
    &#39;[object Boolean]&#39; : &#39;boolean&#39;, 
    &#39;[object Number]&#39;  : &#39;number&#39;, 
    &#39;[object String]&#39;  : &#39;string&#39;, 
    &#39;[object Function]&#39; : &#39;function&#39;, 
    &#39;[object Array]&#39;  : &#39;array&#39;, 
    &#39;[object Date]&#39;   : &#39;date&#39;, 
    &#39;[object RegExp]&#39;  : &#39;regExp&#39;, 
    &#39;[object Undefined]&#39;: &#39;undefined&#39;,
    &#39;[object Null]&#39;   : &#39;null&#39;, 
    &#39;[object Object]&#39;  : &#39;object&#39;
  };
  if(obj instanceof Element) {
    return &#39;element&#39;;
  }
  return map[toString.call(obj)];
}

Übergeben Sie zuerst JSON.stringify und dann JSON.parse, um eine tiefe Kopie zu erhalten. Der Datentyp unterstützt jedoch nur grundlegende numerische Typen.

var obj = {
  a: &#39;a&#39;, 
  b: function(){console.log(&#39;b&#39;)}
}
 
//在JSON.stringify的时候就会把function给过滤了。
 
JSON.stringify(obj)// "{"a":"a"}"

Zusammenfassung

Hier finden Sie eine Zusammenfassung von Deep Copy und wie Sie eine Deep Copy implementieren. In verschiedenen Szenarien muss anhand des Geschäftsszenarios ermittelt werden, ob Deep Copy verwendet werden muss.

Ausführlichere Erläuterungen zu Javascript Deep Copy (deepClone) und verwandten Artikeln finden Sie auf der chinesischen PHP-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