02. Copying Objects
Object.assign
Object.assign
Функция Object.assign
получает список объектов и копирует в первый target
свойства из остальных. При этом последующие свойства перезаписывают предыдущие. Этот прием так же можно использовать для поверхностного копирования.
Object.assign(target, src1, src2...)
const user = { name: "Вася" };
const visitor = { isAdmin: false, visits: true };
const admin = { isAdmin: true };
Object.assign(user, visitor, admin); // name: Вася, visits: true, isAdmin: true
// clone = пустой объект + все свойства user
const user = { name: "Вася", isAdmin: false };
const clone = Object.assign({}, user);
Особенности:
Object.assign
копирует как строковые ключи, так и символьныеКопируются только собственные перечисляемые свойства. Унаследованные и неперечисляемые свойства игнорируются.
Чтение свойства - это обычная операция получения свойства. Если свойство представляет собой метод доступа, то копируется только полученное значение, а не сам метод.
Запись свойства в
target
- это обычная операция присваивания свойства. Функции setter-ы не копируются.Нельзя скопировать метод, использующий
super
в другой объект.
Для полного копирования всех свойств, включая копирование методов доступа необходимо использовать следующие функции:
function copyAllProperties(target, ...sources) {
for (const source of sources) {
for (const key of Reflect.ownKeys(source)) {
const desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
return target;
}
Способ 2:
const clone = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
Метод Object.assign
можно использовать для заполнения значений по умолчанию:
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
options = Object.assign({}, DEFAULTS, options); // (A)
···
}
A method that uses super is firmly connected with its home object (the object it is stored in). There is currently no way to copy or move such a method to a different object.
Deep copy
Для создания полностью идентичной копии другого объекта необходимо выполнить два шага:
Копия должна иметь тот же прототип
Копия должна иметь те же атрибуты с теми же значениями, что и оригинал.
function copyObject(orig) {
// 1. copy has same prototype as orig
const copy = Object.create(Object.getPrototypeOf(orig));
// 2. copy has all of orig’s properties
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source).forEach(function(propKey) {
// (1), (2)
const desc = Object.getOwnPropertyDescriptor(source, propKey); // (3)
Object.defineProperty(target, propKey, desc); // (4)
});
return target;
}
Шаги алгоритма:
Get an array with the keys of all own properties of source.
Iterate over those keys.
Retrieve a property descriptor.
Use that property descriptor to create an own property in target.
Last updated
Was this helpful?