Поиск в Google для «javascript clone object» приносит действительно странные результаты, некоторые из них безнадежно устарели, а некоторые слишком сложны, не так ли просто, как просто:
let clone = {...original};
Что-то не так с этим?
javascript
ecmascript-6
javascript-objects
Дмитрий Фадеев
источник
источник
original = { a: [1,2,3] }
дает вам клон сclone.a
буквально существомoriginal.a
. Модификация не с помощью либоclone
илиoriginal
модифицирует одно и то же , так что нет, это плохо =)Ответы:
Это хорошо для мелкого клонирования . Распространение объекта является стандартной частью ECMAScript 2018 .
Для глубокого клонирования вам понадобится другое решение .
const clone = {...original}
клонироватьconst newobj = {...original, prop: newOne}
непременно добавьте другую опору к оригиналу и сохраните как новый объект.источник
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
не сработает, потому что если тамfunctions
илиinfinity
как значения он просто назначитnull
на их место. Это будет работать только в том случае, если значения просты,literals
а неfunctions
.РЕДАКТИРОВАТЬ: Когда этот ответ был опубликован,
{...obj}
синтаксис был недоступен в большинстве браузеров. В настоящее время, вы должны нормально использовать его (если вам не нужно поддерживать IE 11).Используйте Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Тем не менее, это не сделает глубокий клон. Пока нет родного способа глубокого клонирования.
РЕДАКТИРОВАТЬ: Как @Mike 'Pomax' Kamermans упомянул в комментариях, вы можете глубоко клонировать простые объекты (т.е. без прототипов, функций или циклических ссылок), используя
JSON.parse(JSON.stringify(input))
источник
JSON.parse(JSON.stringify(input))
это правильный глубокий клон. Однако в тот момент, когда прототипы, функции или циклические ссылки находятся в игре, это решение больше не работает.Если используемые вами методы плохо работают с объектами, включающими такие типы данных, как Date , попробуйте это
Импортировать
_
Глубокий клон
источник
import _ from 'lodash';
достаточно. Но +1 за ответ "не изобретай велосипед".если вы не хотите использовать json.parse (json.stringify (object)), вы можете создать рекурсивные копии со значением ключа:
Но лучший способ - создать класс, который может сам возвращать клон
источник
Следуя ответу @marcel, я обнаружил, что некоторые функции все еще отсутствуют в клонированном объекте. например
где на MyObject я мог клонировать methodA, но methodB был исключен. Это произошло потому, что оно отсутствует
что означало, что он не появился в
Вместо этого я переключился на
который будет включать не перечисляемые ключи.
Я также обнаружил, что прототип ( proto ) не был клонирован. Для этого я использовал
PS: расстраивает, что не смог найти встроенную функцию для этого.
источник
Вы можете сделать это так же,
источник
Но Object.assign () не создает глубокий клон
Чтобы исправить это, мы должны использовать цикл клонирования, который проверяет каждое значение user [key] и, если это объект, затем копирует его структуру. Это называется «глубокое клонирование».
Существует стандартный алгоритм глубокого клонирования, который обрабатывает описанный выше случай и более сложные случаи, называемый алгоритмом структурированного клонирования . Чтобы не изобретать велосипед, мы можем использовать рабочую реализацию из библиотеки JavaScript lodash метод называется _.cloneDeep (объект) .
источник
Все описанные выше методы не обрабатывают глубокое клонирование объектов, если оно вложено в n уровней. Я не проверял его производительность по сравнению с другими, но он короткий и простой.
В первом примере ниже показано клонирование объектов с использованием
Object.assign
клонов до первого уровня.Используя приведенный ниже подход, глубоко клонируем объект
источник