2012-05-08 18 views
9

Ho cercato ovunque e ho trovato domande simili con risposte che non risolvevano il problema, quindi mi scuso se sembra una ripetizione, ma dal mio esperimento risulta che la funzione di copia profonda di jQuery non funziona come descritto (o forse sto fraintendendo la sua descrizione).Perché jQuery Extend Deep Copy non copia ricorsivamente un oggetto?

Ecco un esempio che illustra il problema che sto avendo: http://jsfiddle.net/wcYsH/

O questo per il download: https://github.com/kevroy314/jQuery-Extend-Test

Perché i dati nella copia precedente ottenere cambiato quando la copia profonda è manipolato?

+1

Vuoi utilizzare '' .clone' di 'jQuery' invece? –

+1

C'era una discussione su questo nei forum di jQuery di recente. Penso che il tuo caso non rientri nello scopo del $ ThOD. https://forum.jquery.com/topic/deep-copies-using-extend-on-object-instances –

+1

Ecco un ticket relativo ai bug http://bugs.jquery.com/ticket/10014 –

risposta

5

Per uno, non si stanno creando oggetti normali.

Sto guardando il codice sorgente per jQuery 1.7.2 per l'estensione.

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

E sto notando la linea:

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

deve valutare a true di fare una copia profonda. la copia è solo una parte dell'oggetto corrente che viene copiato.

Ma non si stanno creando oggetti "semplici". Stai creando oggetti generati invocando un costruttore con il nuovo operatore.

Ora, in isPlainObject, sembra che queste linee debbano essere valutate. (Dove hasOwn è 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; 
    } 

E c'è dove si conclude che non è un "plainObject".

Questo ha senso se si considera gli oggetti con un costruttore probabilmente dovrebbero essere creati tramite quel costruttore o almeno usa un metodo "clone" come vedresti in altri linguaggi/framework

+1

Grazie! Questa è la spiegazione che stavo cercando. Sono andato avanti e ho scritto una funzione .clone per ogni oggetto che ho creato. Sfortunatamente, il modo hacky che stavo usando. Apparentemente sembrava copiare gli oggetti abbastanza in profondità da far funzionare la mia applicazione, ma abbastanza superficiale da non sprecare memoria, quindi ora la mia implementazione è un orrendo maiale della memoria! Torna al tavolo da disegno! – user986122