Функции-конструкторы

Принцип создания функции-конструктора


Функция по своей сути является объектом, поэтому мы можем записать в неё какие-то методы и свойства. Давайте создадим какую-то функцию, назовём её User, и у неё будет два аргумента name и id:

Код

function User(name, id) {

}

По аналогии с объектом, запишем в нашу функцию свойства, при этом будем использовать ключевое слово this, поскольку мы будем работать с каждым конкретным пользователем (у каждого будет своё имя и номер)
Запишем три свойства, первое будет отображать имя конкретного пользователя, второе - его возраст и третье, общее для всех, будет указывать, что это человек.

Код

function User(name, id) {
  this.name = name;
  this.id = id;
  this.human = true;
}

Мы создали функцию-конструктор и теперь с её помощью мы можем создавать новых пользователей. Делается это с помощью оператора new, общий синтаксис при этом следующий:

Код

new имя_функции_конструктора(аргументы)

Давайте создадим пару пользователей и сохраним их в переменных, при этом, поскольку оператор new создаёт экземпляр объекта, то внутри переменных у нас и сохранятся объекты, с теми свойствами, которые мы прописали в функции-конструкторе:

Код

const ivan = new User('Ivan', 25);
const alex = new User('Alex', 30);

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

Код

User { name: 'Ivan', id: 25, human: true }
User { name: 'Alex', id: 30, human: true }

Мы сконструировали два разных объекта, но они визуально подобны, поскольку использовалась одна и та же функция-конструктор.

Итак, еще раз, по шагам:

1. Функция-конструктор задаёт тип объекта, его свойства и методы

2. Аргументы функции-конструктора - это список параметров, с которыми она будет вызвана

3. С помощью оператора new создаём объекты, используя имеющуюся функцию-конструктор с заданными параметрами

В нашем случае, например, создался экземпляр объекта с именем ivan, при этом его свойствам присваиваются указанные значения: ivan.name принимает значение "Ivan", ivan.id принимает значение 25.

Методы внутри функции-конструктора


В функции-конструкторе мы можем использовать также методы, например, добавим в нашу функцию-конструктор метод helloy:

Код

function User(name, id) {
  this.name = name;
  this.id = id;
  this.human = true;
  this.helloy = function() {

  };
}

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

Код

function User(name, id) {
  this.name = name;
  this.id = id;
  this.human = true;
  this.helloy = function() {
  console.log(`Helloy ${this.name}`);
  };
}

Если сейчас мы пропишем :

Код

ivan.helloy();
alex.helloy();

и запустим такой код, то в консоли увидим как отработал наш метод:

Код

Helloy Ivan
Helloy Alex

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

Давайте добавим какой-нибудь метод logout (пользователь вышел из системы, разлогинился) в нашу функцию-конструктор:

Код

User.prototype.logout = function() {

};

Как результат работы функции выведем в консоль сообщение, что пользователь такой-то ушел:

Код

User.prototype.logout = function() {
  console.log(`Пользователь ${this.name} ушёл`);
};

Этот метод будет теперь наследоваться всеми потомками, созданными после него

Код

function User(name, id) {
  this.name = name;
  this.id = id;
  this.human = true;
  this.helloy = function() {
  console.log(`Helloy ${this.name}`);
  };
}

User.prototype.logout = function() {
  console.log(`Пользователь ${this.name} ушёл`);
};

const ivan = new User('Ivan', 25);
const alex = new User('Alex', 30);

чтобы в этом убедиться, тестируем:

Код

ivan.logout();

В консоли увидим как отработал наш метод:

Код

Пользователь Ivan ушёл

Используем объект в качестве свойства другого объекта


Возьмём уже имеющийся у нас конструктор User:

Код

function User(name, id) {
  this.name = name;
  this.id = id;
  this.human = true;
}

у нас есть два созданных экземпляра объекта:

Код

const ivan = new User('Ivan', 25);
const alex = new User('Alex', 30);

и создадим еще одну функцию-конструктор, назовём её Car:

Код

function Car(brand, model, year, own) {
  this.brand = brand;
  this.model = model;
  this.year = year;
  this.own = own;
}

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

Код

const auto1 = new Car('Audi', 'A6', 2015, ivan);
const auto2 = new Car('BMW', 'X6', 2018, alex);

В качестве последнего аргумента мы используем переменные ivan и alex, как вы помните, в этих переменных у нас содержатся объекты, содержащие свойства, заданные в функции-конструкторе User.

И теперь, чтобы вывести в консоль, например, имя владельца второй машины, можно сделать так:

Код

console.log(auto2.own.name);

Результат в консоли ожидаем:

Код

Alex

Как так получается?
В данном случае создан экземпляр объекта с именем auto2, при этом его свойствам присваиваются указанные значения: auto2.brand принимает значение "BMW", auto2.model принимает значение "X6",
auto2.year принимает значение 2018, а вот auto2.own в качестве значения принимает объект из переменной alex.
Имя в этом объекте хранится в свойстве name, обратившись к которому мы и получаем его значение Alex. В этом можно убедиться, если вывести в консоль содержимое переменной auto2:

Код

Car {
  brand: 'BMW',
  model: 'X6',
  year: 2018,
  own: User { name: 'Alex', id: 30, human: true }
}

Комментарии к материалу: