JavaScript частично является объектно-ориентированным языком.
Чтобы изучить JavaScript, нам нужно изучить объектно-ориентированные части JavaScript.
В этой статье мы рассмотрим копирование объектов.
Глубокая копия
Мы можем глубоко скопировать объект, рекурсивно копируя его свойства из исходного объекта в целевой.
Например, мы можем написать:
function deepCopy(source, target = {}) { for (const key in source) { if (source.hasOwnProperty(key)) { if (typeof source[key] === 'object') { target[key] = Array.isArray(source[key]) ? [] : {}; deepCopy(source[key], target[key]); } else { target[key] = source[key]; } } } return target; }
Мы перебираем каждую клавишу source
.
Затем мы проверяем каждое свойство, если это собственное свойство.
Затем мы проверяем, является ли объект source[key]
объектом.
Если source[key]
- это массив, мы создаем массив, а затем выполняем копирование.
Если это объект, мы рекурсивно вызываем deepCopy
, чтобы сделать копию.
В противном случае мы присваиваем значение из source
target
.
После этого мы возвращаем target
.
Затем мы можем использовать его, написав:
const foo = { a: 1, b: { c: 2 } } const bar = deepCopy(foo, {}); console.log(bar);
deepCopy
рекурсивно скопирует все собственные свойства из foo
в bar
.
So bar
is:
{ "a": 1, "b": { "c": 2 } }
Array.isArray
позволяет нам проверять, является ли что-то массивом, независимо от контекста.
Использование метода object ()
Мы можем создать object
функцию для создания функции, возвращающей экземпляр конструктора.
Это предложение от Дугласа Крокфорда, и оно упрощает настройку прототипа, поскольку принимает объект прототипа.
Например, мы можем написать:
function object(proto) { function F() {} F.prototype = proto; return new F(); }
Мы создаем функцию object
со свойством proto
.
Затем мы установили это как F
‘s prototype
.
И мы возвращаем экземпляр F
.
Это отличается от Object.create
, поскольку у нас есть экземпляр конструктора.
Затем мы можем использовать его, написав:
const obj = object({ foo: 1 });
Тогда obj
унаследует объект, который мы передали.
Сочетайте свойства прототипного наследования и копирования
Мы можем смешивать прототипное наследование с копированием свойств.
Для этого мы можем расширить функцию object
, написав:
function object(proto, moreProps) { function F() {} F.prototype = proto; const f = new F(); return { f, ...moreProps }; } const obj = object({ foo: 1 }, { bar: 2 });
Мы добавляем параметр moreProps
к функции object
, что позволяет нам добавлять дополнительные свойства, передавая ей второй аргумент.
moreProps
распространяется на объект, который мы возвращаем, так что мы возвращаем новый объект.
Следовательно, obj
это {f: F, bar: 2}
, поскольку мы наследуем от F.prototype
и moreProps
.
Заключение
Мы можем смешивать прототипное наследование с копированием свойств, чтобы получить все свойства, которые нам нужны в объекте.
Глубокое копирование может быть выполнено путем рекурсивного копирования свойств из исходного объекта в целевой.