Все мы так или иначе имеем дело с объектами при написании кода на любом языке программирования. В JavaScript объекты являются мощным инструментом, который предоставляет нам возможности хранить, обрабатывать и отправлять данные.

Существует несколько способов, которыми JavaScript позволяет нам создавать объекты.

Создание объектов с использованием синтаксиса литерала

Это самый простой способ. Все, что вам нужно сделать, это поместить через запятую пары ключ-значение, разделенные двоеточием, в фигурные скобки, и ваш объект готов к использованию:

const person = {
  firstName: 'Иван',
  lastName: 'Петров'
};

Такой способ является самым популярным при создании объекта.

Создание объектов с использованием ключевого слова new

Этот метод создания объектов напоминает способ создания объектов в языках, основанных на классах, таких как Java. Начиная со спецификации ES6, классы также встроены в JavaScript, и мы рассмотрим ниже создание объектов путем определения классов. Итак, чтобы создать объект с использованием ключевого слова new, вам нужна функция-конструктор.

Есть два способа использования шаблона ключевого слова new.

Использование ключевого слова new со встроенной функцией конструктора объектов

Чтобы создать объект, используйте ключевое слово new с конструктором Object(), например:

const person = new Object();

Теперь, чтобы добавить этому объекту свойства, нужно прописать:

person.firstName = 'Иван';
person.lastName = 'Петров';

Выглядит такой метод немного длиннее, чем литеральный. Кроме того, такая практика не рекомендуется, поскольку под капотом скрипта дополнительно будет происходить определение, является ли функция конструктора встроенной или определяемой пользователем.

Использование new с функцией конструктора, определяемой пользователем

Другая проблема при подходе с использованием функции конструктора Object() связана с тем, что каждый раз, когда мы создаем объект, мы должны вручную добавлять свойства к созданному объекту.

Что, если бы нам пришлось создать сотни объектов, подобных нашему person? Можно представить себе эту боль. Чтобы избавиться от ручного добавления свойств к объектам, мы создаем настраиваемые (или определяемые пользователем) функции. Сначала мы создаем функцию-конструктор, а затем используем ключевое слово new для получения объектов:

function Person(fname, lname) {
  this.firstName = fname;
  this.lastName = lname;
}

Теперь, всякий раз, когда необходимо будет создать объект персоны, просто выполните следующее:

const personOne = new Person('Иван', 'Петров');
const personTwo = new Person('Петр', 'Иванов');

Создание объектов с помощью Object.create()

Этот шаблон очень удобен, когда нас просят создать объекты из других существующих объектов, а не напрямую с использованием синтаксиса ключевого слова new. Давайте посмотрим, как использовать этот шаблон. Как сказано на MDN:

Метод Object.create() создает новый объект, используя существующий объект в качестве прототипа вновь созданного объекта.

Чтобы понять метод Object.create, просто помните, что он принимает два параметра. Первый параметр - это обязательный объект, который служит прототипом нового создаваемого объекта. Второй параметр - это необязательный объект, который содержит свойства, добавляемые к новому объекту.

Мы не будем сейчас углубляться в прототипы и цепочки наследования, чтобы сосредоточиться на этой теме. Но вкратце: вы можете думать о прототипах как об объектах, из которых другие объекты могут заимствовать необходимые им свойства / методы.

Представьте, что у вас есть компания, представленная объектом orgObject.

const orgObject = { company: 'Моя компания' };

И вы хотите создать сотрудников для вашей компании. Логично, что вам нужно каждому указать данные компании.

const employee = Object.create(orgObject, { name: { value: 'Иван' } });

console.log(employee.company);  // => "Моя компания"
console.log(employee.name);  // => "Иван"

Использование Object.assign() для создания новых объектов

А что, если мы хотим создать объект, который должен иметь свойства более чем одного объекта? Тогда на помощь приходит Object.assign(). Как сказано на MDN:

Метод Object.assign() используется для копирования значений всех собственных свойств из одного или нескольких исходных объектов в целевой объект. Он возвращает целевой объект.

Метод Object.assign может принимать любое количество объектов в качестве параметров. Первый параметр - это объект, который он создаст и вернет. Остальные переданные ему объекты будут использоваться для копирования свойств в новый объект. Давайте разберемся в этом, расширив предыдущий пример, который мы видели.

Предположим, у вас есть два объекта:

const orgObject = { company: 'Моя компания' };
const carObject = { carName: 'Ford' };

И теперь вам нужен объект сотрудника "Моя компания", который водит автомобиль "Ford". Вы можете сделать это с помощью Object.assign, как показано ниже:

const employee = Object.assign({}, orgObject, carObject);

Теперь вы получаете объект сотрудника, у которого в качестве свойства есть и компания и автомобиль.

console.log(employee); // { carName: 'Ford', company: 'Моя компания' }

Использование классов ES6 для создания объекта

Вы наверняка заметите, что этот метод аналогичен использованию new с функцией конструктора, определяемой пользователем. Однако функции конструктора теперь заменены классами, поскольку они поддерживаются спецификацией ES6. Посмотрим на код:

class Person {
  constructor(fname, lname) {
    this.firstName = fname;
    this.lastName = lname;
  }
}

const person = new Person('Иван', 'Петров');

console.log(person.firstName);  // => Иван
console.log(person.lastName);  // => Петров