Не рекомендуется делать расширения Прототипа, это приведет к проблемам, когда вы будете делать тесты своего кода / компонентов. Фреймворки модульного тестирования не будут автоматически принимать расширения вашего прототипа. Так что это плохая практика. Здесь есть больше объяснений расширений прототипов. Почему расширение собственных объектов - плохая практика?
Для клонирования объектов в JavaScript нет простого и понятного способа. Вот первый пример, использующий «Мелкую копию»:
1 -> Мелкий клон:
class Employee {
constructor(first, last, street) {
this.firstName = first;
this.lastName = last;
this.address = { street: street };
}
logFullName() {
console.log(this.firstName + ' ' + this.lastName);
}
}
let original = new Employee('Cassio', 'Seffrin', 'Street A, 23');
let clone = Object.assign({},original);
let cloneWithPrototype Object.create(Object.getPrototypeOf(original)), original)
let clone2 = { ...original };
clone.firstName = 'John';
clone.address.street = 'Street B, 99';
Полученные результаты:
original.logFullName ():
результат: Кассио Сеффрин
clone.logFullName ():
результат: Джон Сеффрин
original.address.street;
result: 'Street B, 99' // обратите внимание, что исходный подобъект был изменен
Примечание: если у экземпляра есть замыкания как собственные свойства, этот метод не будет его переносить. ( подробнее о замыканиях ) И, кроме того, подобъект «адрес» не будет клонирован.
clone.logFullName ()
не будет работать.
cloneWithPrototype.logFullName ()
будет работать, потому что клон также скопирует свои прототипы.
Чтобы клонировать массивы с помощью Object.assign:
let cloneArr = array.map((a) => Object.assign({}, a));
Клонировать массив с использованием синтаксиса распространения ECMAScript:
let cloneArrSpread = array.map((a) => ({ ...a }));
2 -> Глубокий клон:
Чтобы заархивировать полностью новую ссылку на объект, мы можем использовать JSON.stringify () для синтаксического анализа исходного объекта как строки и после синтаксического анализа обратно в JSON.parse ().
let deepClone = JSON.parse(JSON.stringify(original));
При глубоком клонировании ссылки на адрес будут сохранены. Однако прототипы deepClone будут потеряны, поэтому deepClone.logFullName () не будет работать.
3 -> сторонние библиотеки:
Другой вариант - использовать сторонние библиотеки, такие как loadash или подчеркивание. Они создадут новый объект и скопируют каждое значение из оригинала в новый объект, сохраняя его ссылки в памяти.
Подчеркивание: let cloneUnderscore = _ (оригинал) .clone ();
Клон Loadash: var cloneLodash = _.cloneDeep (оригинал);
Обратной стороной lodash или подчеркивания была необходимость включения в ваш проект дополнительных библиотек. Однако они являются хорошими вариантами и также дают высокие результаты производительности.