Сегодня мы рассмотрим Конструкторы JavaScript, но для начала вот список статей на тему «Объекты в JavaScript»:
- Объекты основанные на прототипах
- Прототипы JavaScript
- Свойства класса JavaScript
- Наследование через цепочку прототипов
Конструкторы JavaScript
Экземпляры объектов создаются с помощью конструкторов JavaScript, представляющих собой специальные функции, которые подготавливают новые экземпляры объекта для использования. Конструктор содержит прототип объекта, который и определяет программный код и данные, получаемые каждым экземпляром объекта по умолчанию. Вы уже видели множество примеров создания объектов, например:
1 |
var s = new String(); |
В этой строке вызывается конструктор объекта String — функция с именем String (). JavaScript «знает», что эта функция является конструктором, поскольку она вызывается в совокупности с операцией new.
Можно определить собственный конструктор с помощью функции:
1 2 3 4 |
function Robot() { } |
Эта функция сама по себе ничего не делает. Но ее можно вызвать как конструктор — точно так же, как мы только что делали это для String ():
1 |
var guard = new Robot(); |
Мы создали экземпляр объекта
Robot. Очевидно, польза от этого объекта не слишком велика. Чтобы продолжить обсуждение, нам потребуется дополнительная информация о построении объектов.
При вызове конструктора интерпретатор выделяет память для нового объекта и неявно передает новый объект соответствующей функции. Конструктор может получить доступ к создаваемому объекту, используя this — специальное ключевое слово, содержащее ссылку на новый объект. Интерпретатор делает this доступным, чтобы конструктор мог работать с создаваемым им объектом. Например, это ключевое слово можно использовать для установки значений по умолчанию. Давайте переопределим наш конструктор, чтобы отразить указанную возможность:
1 2 3 4 |
function Robot() { this.hasJetpack = true; } |
Здесь добавляется новое свойство экземпляра has Jetpack, которое будет содержать каждый новый объект, создаваемый с помощью этого конструктора. После создания объекта с помощью конструктора, мы получим доступ к свойству has Jetpack, как и ожидается:
1 2 |
var guard = new Robot(); var canFly = guard.hasJetpack; |
Поскольку конструкторы являются функциями, им можно передавать аргументы, чтобы указать начальные значения. Можно снова изменить наш конструктор так, чтобы он принимал необязательный аргумент:
1 2 3 4 5 6 7 8 9 10 11 |
function Robot(needsToFly) { if (needsToFly == true) this.hasJetpack = true; else this.hasJetpack = false; } // создает Robot с hasJetpack == true var guard = new Robot(true); // создает Robot с hasJetpack == false var sidekick = new Robot(); |
В этом примере мы могли бы явно передать значение false при создании экземпляра s idekick. Но, не передав ничего, мы неявно сделали то же самое, поскольку параметр needsToFly в этом случае получает значение undefined. Поэтому условие оператора if оказывается ложным, как и требуется.
В создаваемый объект можно добавлять и методы. Одним из вариантов здесь является назначение некоторой переменной экземпляра подходящей анонимной функции внутри конструктора, точно так же, как выше добавлялось свойство экземпляра. Однако это оказывается слишком расточительным с точки зрения затрат памяти, поскольку собственную копию этой функции будет иметь каждый созданный объект. Лучшим способом достижения той же цели было бы использование прототипа объекта.