2012-07-02 17 views
30

Powiel możliwe:
What is the most efficient way to clone a JavaScript object?JavaScript Object głębokie kopiowanie

mam obiektu takiego:

User = {  
    name: "user", 
    settings: { 
    first: "1", 
    second: "2"  
    }  
} 

i drugi:

user1 = { 
    name: "user1", 
    settings: { 
    second: "3" 
    } 
} 

teraz chcę skopiować niestandardowe wartości user1 jest do Użytkownika, używając:

for(var key in user1){ 
     User[key] = user1[key]; 
    } 

wynikiem Użytkownik będzie:

User = { 
    name: "user1", 
    settings: { 
    second: "3" 
    } 
} 

USER.settings został całkowicie zastąpić, a ja chciałem tylko settings.second do zastąpienia.

Jak to osiągnąć, nie wiedząc, ile obiektów podrzędnych ma obiekt główny?

+2

Użyj rekursji? Czy szukałeś głębokich funkcji Object.copy? – Bergi

+0

Czy można użyć jQuery? –

+0

Z powodu tego, w jaki sposób javascript przekazuje obiekty wokół (przez odniesienie), głębokie kopiowanie zagnieżdżonego obiektu jest w rzeczywistości dość ciężkim doświadczeniem. Postępowałem zgodnie z radą @ Bergi i znajdowałem wcześniejszą. –

Odpowiedz

14

Znalazłem, że najlepszym sposobem, aby przejść to:

http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/

Object.deepExtend = function(destination, source) { 
    for (var property in source) { 
    if (typeof source[property] === "object" && 
    source[property] !== null) { 
     destination[property] = destination[property] || {}; 
     arguments.callee(destination[property], source[property]); 
    } else { 
     destination[property] = source[property]; 
    } 
    } 
    return destination; 
}; 


Object.extend(destination, source); 

Co na ten temat?

function clone(destination, source) { 
     for (var property in source) { 
      if (typeof source[property] === "object" && source[property] !== null && destination[property]) { 
       clone(destination[property], source[property]); 
      } else { 
       destination[property] = source[property]; 
      } 
     } 
    }; 
+1

arguments.callee jest przestarzałe. Powinieneś naprawdę używać nazwanej funkcji. Ponadto zapomniałeś o hasOwnProperty, co jest bardzo istotne. – Bergi

+0

zobacz aktualizację, czy to lepiej? –

+0

Tak, chociaż nadal kopiuje się właściwości z prototypu. Kopiowanie do obiektu docelowego powinno być nazywane "rozszerzeniem", a nie "klonowaniem" ("deepextend" z pierwszej próby byłoby jeszcze lepsze) – Bergi

-1

To jest naprawdę hacky, ale to powinno zadziałać. Proponuję robić tak, jak sugerowali inni użytkownicy w komentarzach; znajdź istniejącą wcześniej bibliotekę, która zrobi to za Ciebie.

for(var key in user1){ 
    var temp = User[key] 
    User[key] = user1[key]; 
    for(var key1 in temp){ 
     if(User[key][key1] == null){ 
     User[key][key1] = temp[key1]; 
     } 
    } 
} 
+0

obiekt, który wysłałem, był przykładem, w którym szukam czegoś, co zadziała wszędzie –

+1

O ok. Cóż, chciałbym rzucić okiem na jQuerys http://api.jquery.com/jQuery.extend/, wygląda na to, że może zrobić dokładnie to, czego szukasz. –

+0

znalazłem to, co wydaje się działać (nie jest to idealne, ale początek) http://my.opera.com/GreyWyvern/blog/show.dml/1725165, dla jquery Chciałbym kkep to agnostic ramy –

4

Chwycił rozszerzenia metody jQuery, a stało się biblioteka agnostykiem.

Streszczenie: Library agnostic version of jQuery's Extend

Jej owinięte w konstruktorze Extender, dzięki czemu nie trzeba instancję wszystkich swoich wewnętrznych metod przy każdym wywołaniu metody przedłużenia.

Nota prawna: Nie testowałem tego dokładnie. Zasadniczo jest to klon jQuery (1: 1), jednak twój przebieg może się różnić.

Użyj tego w ten sposób.

var user1 = { 
    name: "user1", 
    settings: { 
    first: "1", 
     second: {bar: 'foo'} 
    } 
}; 
var user2 = { 
    name: "user2", 
    settings: { 
    second: {foo:'bar'} 
    } 
}; 

/* merge user1 into User */ 
__extend(true, user1, user2); 

// Modifies the User object 
user1.settings.second.foo == 'bar'; // true 

// note, you can do assignment too. 
var newUser = __extend(true, user1, user2); 

See here for more documentation

+0

To może być dłuższe niż inne rozwiązania, ale działa niezawodnie i działa zarówno na typy tablicowe, jak i obiektowe. Dziękuję Ci! –

+0

Pomogło mi to w nosorożcu .. Pozdrawiam –

Powiązane problemy