Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Клонирование объекта в javascript (https://javascript.ru/forum/misc/56683-klonirovanie-obekta-v-javascript.html)

Casufi 28.06.2015 23:48

Клонирование объекта в javascript
 
В яваскрипте объекты передаются по ссылке. Возникла необходимость в клонировании объектов. Вопрос, есть ли подводные камни у подхода, реализованного ниже ?

function cloneObject(obj) {
    var clone = {};
    for (var i in obj) {
        if (typeof (obj[i]) == "object" && obj[i] != null) clone[i] = cloneObject(obj[i]);
        else clone[i] = obj[i];
    }
    return clone;
}


http://jsfiddle.net/0vnzxh94/1/

Malleys 29.06.2015 01:23

Попытаемся клонировать HTML-элемент, а потом подключить его к DOM:
document.body.appendChild(clone(document.createElement('input')));

Произошла ошибка: TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
После клонирования наш элемент стал «просто» объектом.

Такая же ситуация с...
...числами и строками: clone(5) + clone(6) оказывается равным "[object Object][object Object]", а не 11
clone("OMG").toLowerCase() ==> TypeError: clone(...).toLowerCase is not a function

...массивами: clone([1,2]).push(3) ==> TypeError: clone(...).push is not a function

Для того, чтобы создать клон объекта, нам надо знать кто был его конструктором. При помощи этого можно создать «точную» копию объета. Т. е. клоном массива будет массив, а не «просто» объект. Правда такой трюк не срабатывает с HTML-элементом(TypeError: Illegal constructor). Но в таком случае можно использовать cloneNode.

Учитывая всё выше сказанное можно составить такую функцию
function clone(object) {
  if(object && typeof object === "object" && object !== null && object.nodeType === 1 && typeof object.nodeName==="string") {
    return object.cloneNode(false);
  }

  return new (object.constructor)(object);
}


Часовой пояс GMT +3, время: 16:45.