2010-09-22 6 views
16

Можно создать дубликат:
How to clone js object?Клонирование объекта JavaScript?

Это еще один способ создания объектов JavaScript (с помощью объекта буквального обозначения вместо функции):

user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

Есть ли способ клонировать этот объект или это одноэлемент?

+3

Объект JavaScript! = Объект JSON. Приведенный вами пример является литералом объекта JavaScript; Я обновил ваше сообщение соответственно. –

+0

хороший вопрос! Я всегда буду думать, что user2 = пользователь сделает копию, но не буду. – Topera

+1

Самый короткий «ответ»: да и да. ;) –

ответ

26

Попробуйте следующее:

var clone = (function(){ 
    return function (obj) { Clone.prototype=obj; return new Clone() }; 
    function Clone(){} 
}()); 

Вот что происходит.

  • Клон - это конструктор-пустышка.
  • Мы назначаем объект, который мы хотим клонировать к прототипу конструктора Clone.
  • Мы вызываем Clone с использованием «new», поэтому построенный объект имеет исходный объект как прототип своего конструктора aka (нестандартный) __proto__.

Клонированный объект будет обладать всеми свойствами исходного объекта без каких-либо копий чего-либо. Если свойствам клонированного объекта присваиваются новые значения, они не будут мешать исходному объекту. И никаких подделок встроенных модулей не требуется.

Имейте в виду, что свойство объекта вновь созданного объекта будет ссылаться на тот же объект, что и одноименное свойство клонированного объекта. Назначение нового значения для свойства клона не будет мешать оригиналу, но присвоение значений свойствам объекта clone будет.


Попробуйте хромированной или Firebug консоли:

var user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

var clonedUser = clone(user); 

console.dir(clonedUser); 

Подробное объяснение этого метода клонирования можно найти here.

+2

'user = {name:" ", email:" ", obj: {a:" A "}}; clonedUser = clone (user); ',' clonedUser.obj.a = "B"; 'вы найдете' user.obj.a == "B" ' – vol7ron

+0

Это выглядит очень похоже на ответ Криса Дж. – vol7ron

+0

vol7ron: да, потому что user.obj и clonedUser.obj относятся к одному и тому же объекту. Присвоение нового значения атрибуту 'obj' newUser не будет проявляться. Запрос был для клона, а не для копии, а не для глубокой копии. См. Ссылку в конце моего ответа. –

2

Большинство фреймворков javascript имеют хорошую поддержку клонирования объектов.

var a= {'key':'value'}; 
var b= jQuery.extend(true, {}, a); 
+0

Согласовано: у underscorejs также есть метод клона http://underscorejs.org/#clone – dreftymac

10

Вы можете использовать JSON объект (присутствующий в современных браузерах):

var user = {name: "Foo", email: "[email protected]" } 
var user2 = JSON.parse(JSON.stringify(user)) 

user2.name = "Bar"; 
alert(user.name + " " + user2.name); // Foo Bar 

См jsfiddle.


EDIT

Если вам это нужно в старых браузерах см http://www.json.org/js.html.

+1

хм ... не собираюсь понижать вас, но это просто глупо, на мой взгляд. прежде всего, если вы собираетесь использовать JSON, вам нужно будет включить json2.js на вашу страницу, потому что все еще есть текущие браузеры без встроенного json, и в течение некоторого времени будут использоваться те, которые неактивны. Либо записывайте, либо занимайте расширенную реализацию или включайте библиотеку, в которой она есть. –

+0

Я просто даю еще один способ сделать это. Если на сайте уже есть json2.js, он работает. – Topera

+1

Если у объекта есть как «свойства», так и «методы», мой друг, используя этот стиль JSON, «методы» ** не клонируются ** –

4

Я хотел бы использовать это:

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     var F = function() {}; 
     F.prototype = o; 
    return new F(); 
    }; 
} 

то любой объект, который я хочу, чтобы клонировать можно сделать:

user = { 
    name: "Foo", 
    email: "[email protected]" 
}; 
var user2 = Object.create(user); 

Как показано в (или аналогичные) JavaScript хорошие части

+1

Вы не должны этого делать; см. ответ [Kangax]] (http://stackoverflow.com/questions/3075308/what-modernizer-scripts-exist-for-the-new-ecmascript-5-functions/3075818#3075818) –

+2

@Marcel Спасибо за указание, что вне. Я оставлю свой ответ как есть и рекомендую объяснение Kangax как хорошее чтение. –

+0

@ Marcel/Chris +1; Ответ Kangax состоит только в том, что create не принимает два свойства во всем мире. Я чувствую, что если все используют этот метод, то это вынудит продавцов соблюдать стандарты. Я не использовал FF изначально, потому что он не отображал все правильно, теперь сеть стала умнее, а FF внесла изменения в работу в quirksmode. То же самое будет верно, если программисты ограничиваются стандартами и нажимают браузеры, которые их принимают. – vol7ron

0
Object.prototype.clone = function clone(obj) { 
          obj = obj || this; 
          var new_obj = {}; 

          for(var p in obj) { 
          if (obj.hasOwnProperty(p)) { 
           if(obj[p] !== null && typeof(obj[p]) === "object") { 
           new_obj[p] = clone(obj[p]); 
           } 
           else { 
           new_obj[p] = obj[p]; 
           } 
          } 
          } 

          return new_obj; 
         }; 


/* Example */ 
var foo = { 
    name: "Foo" 
    , email: "[email protected]" 
    , obj: {a:"A",b:"B"} 
}; 

var bar = foo.clone(); 
bar.name = "Bar"; 
bar.obj.b = "C"; 


// foo and bar should have a different 'name' 
// foo and bar should retain the same email 
// foo and bar should have different values for <foo/bar>['obj']['b'] 
// foo and bar should have the same values for <foo/bar>['obj']['a'] 
console.dir(foo); 
console.dir(bar); 
+3

нет нет нет ... никогда не путайте с Object.prototype, вы сломаете все: P –

+2

это неверно, если вы не один из беспилотников, которые используют 'JQuery', то никогда не возиться ни с чем и забыть, как это сделать что-нибудь. – vol7ron

+2

Не расстраивайся. Обычно я избегаю jQuery. Две вещи, хотя ... 1, это не клон, это копия. Название «клонирование» связано с такой техникой: http://oranlooney.com/functional-javascript/ –

Смежные вопросы