У меня есть два хороших ответа в зависимости от того, является ли ваша цель клонировать «простой старый объект JavaScript» или нет.
Давайте также предположим, что вы намереваетесь создать полный клон без ссылок на прототип обратно на исходный объект. Если вас не интересует полный клон, вы можете использовать многие из подпрограмм Object.clone (), представленных в некоторых других ответах (шаблон Крокфорда).
Для простых старых объектов JavaScript проверенный и действительно хороший способ клонирования объекта в современных средах выполнения довольно прост:
var clone = JSON.parse(JSON.stringify(obj));
Обратите внимание, что исходный объект должен быть чистым объектом JSON. То есть все его вложенные свойства должны быть скалярами (например, логическое значение, строка, массив, объект и т. Д.). Любые функции или специальные объекты, такие как RegExp или Date, не будут клонированы.
Это эффективно? Черт возьми, да. Мы перепробовали все виды методов клонирования, и это работает лучше всего. Я уверен, что какой-нибудь ниндзя мог бы придумать более быстрый метод. Но я подозреваю, что мы говорим о предельной прибыли.
Этот подход просто прост и легко реализуем. Оберните его в удобную функцию, и если вам действительно нужно выжать немного, перейдите к более позднему времени.
Теперь для непростых объектов JavaScript не существует простого ответа. На самом деле, этого не может быть из-за динамической природы функций JavaScript и состояния внутреннего объекта. Глубокое клонирование структуры JSON с функциями внутри требует, чтобы вы воссоздали эти функции и их внутренний контекст. И у JavaScript просто нет стандартизированного способа сделать это.
Правильный способ сделать это, опять же, через удобный метод, который вы объявляете и повторно используете в своем коде. Удобный метод может быть наделен некоторым пониманием ваших собственных объектов, так что вы можете быть уверены, что правильно воссоздаете график в новом объекте.
Мы написаны по-своему, но лучший общий подход, который я видел, описан здесь:
http://davidwalsh.name/javascript-clone
Это правильная идея. Автор (Дэвид Уолш) прокомментировал клонирование обобщенных функций. Это то, что вы можете выбрать, в зависимости от вашего варианта использования.
Основная идея заключается в том, что вам нужно специально обрабатывать создание ваших функций (или, так сказать, прототипов) для каждого типа. Здесь он предоставил несколько примеров для RegExp и Date.
Этот код не только краткий, но и очень читаемый. Это довольно легко расширить.
Это эффективно? Черт возьми, да. Учитывая, что цель состоит в том, чтобы создать настоящий клон глубокой копии, вам придется пройтись по элементам графа исходного объекта. При таком подходе вы можете точно настроить, какие дочерние элементы обрабатывать, и как вручную обрабатывать пользовательские типы.
Итак, поехали. Два подхода. Оба, на мой взгляд, эффективны.