2012-05-08 27 views
9

Szukałem wszędzie i znalazłem podobne pytania z odpowiedziami, które tak naprawdę nie rozwiązały mojego problemu, więc przepraszam, jeśli to wygląda jak powtórka, ale z mojego eksperymentowania wynika, że ​​funkcja głębokiego kopiowania jQuery nie działa tak, jak to opisano (a może błędnie odczytuję jej opis).Dlaczego jQuery Extend Deep Copy nie rekursywnie kopiuje obiekt?

Oto przykład wykazanie problem mam: http://jsfiddle.net/wcYsH/

albo to do pobrania: https://github.com/kevroy314/jQuery-Extend-Test

Dlaczego dane w poprzednim egzemplarzu się przebrać, gdy głęboka kopia jest manipulowany?

+1

Czy chcesz użyć 'jQuery'' 'clone' zamiast? –

+1

Na forum jQuery był wątek o tym Ostatnio myślę, że twój przypadek nie mieści się w celu $ .extend me thod. https://forum.jquery.com/topic/deep-copies-using-extend-on-object-instances –

+1

Oto pokrewny komunikat o błędzie http://bugs.jquery.com/ticket/10014 –

Odpowiedz

5

Po pierwsze, nie tworzysz normalnych obiektów.

Zajmuję się kodem źródłowym dla jQuery 1.7.2 do rozszerzenia.

https://github.com/jquery/jquery/blob/master/src/core.js

A ja widząc linię:

if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) 

musi ocenić na true zrobić głębokie kopiowanie. Kopiuj jest tylko częścią kopiowanego obiektu.

Ale nie tworzysz "zwykłych" obiektów. Tworzysz obiekty wygenerowane przez wywołanie konstruktora z nowym operatorem.

Teraz, w isPlainObject, wydaje się, że te linie muszą zostać ocenione. (Gdzie hasOwn jest hasOwn = Object.prototype.hasOwnProperty

try { 
     // Not own constructor property must be Object 
     if (obj.constructor && 
      !hasOwn.call(obj, "constructor") && 
      !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) { 
      return false; 
     } 
    } catch (e) { 
     // IE8,9 Will throw exceptions on certain host objects #9897 
     return false; 
    } 

I tam, gdzie dochodzi do wniosku, że nie jest to „plainObject”.

Ma to sens, jeśli wziąć pod uwagę obiekty z konstruktora prawdopodobnie powinny być tworzone za pośrednictwem tego konstruktora lub najmniej używaj jakiejś metody "klonowania", jak w innych językach/frameworkach:

+1

Dziękujemy! Oto wyjaśnienie, którego szukałem. Poszedłem do przodu i napisałem funkcję .clone dla każdego stworzonego przeze mnie obiektu. Niestety, w zhydny sposób, z jakiego korzystałem .extend najwyraźniej kopiował obiekty na tyle głęboko, że moja aplikacja działała, ale na tyle płytko, żeby nie marnować pamięci, więc teraz moja implementacja jest okropnym wspomnieniem! Powrót do deski kreślarskiej! – user986122

Powiązane problemy