Что такое конструктор в js. Объекты, прототипы и конструкторы в языке JavaScript. Пример создания объекта, определение конструктора, и установка свойства для прототипа

Пример

function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}

Считается хорошей практикой называть функции конструктора с первой буквой верхнего регистра.

Типы объектов (чертежи) (классы)

Примеры из предыдущих глав ограничены. Они только создают одиночные объекты.

Иногда мы нуждаемся в "план " для создания многих объектов одного и того же "типа".

Способ создания "типа объекта", заключается в использовании функции конструктора объектов .

В приведенном выше примере функция Person () является функцией конструктора объектов.

Объекты одного типа создаются путем вызова функции конструктора с помощью ключевого слова New :

var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Sally", "Rally", 48, "green");

Ключевое слово this

В JavaScript, вещь называется это объект, который "владеет" код.

Значение this , при использовании в объекте, является сам объект.

В функции конструктора это значение не имеет. Он заменяет новый объект. Значение этого параметра станет новым объектом при создании нового объекта.

Добавление свойства к объекту

Добавить новое свойство к существующему объекту очень просто:

Пример

myFather.nationality = "English";

Свойство будет добавлено в моего отца. Не моя мать. (не для других объектов Person).

Добавление метода к объекту

Добавить новый метод к существующему объекту очень просто:

Пример

myFather.name = function () {
return this.firstName + " " + this.lastName;
};

Метод будет добавлен в моего отца. Не моя мать. (не для других объектов Person).

Добавление свойства в конструктор

Нельзя добавить новое свойство в конструктор объектов так же, как добавляется новое свойство к существующему объекту:

Пример

Person.nationality = "English";

Чтобы добавить новое свойство в конструктор, необходимо добавить его в функцию конструктора:

Пример


this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.nationality = "English";
}

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

Добавление метода в конструктор

Функция конструктора также может определять методы:

Пример

function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.name = function() {return this.firstName + " " + this.lastName;};
}

Нельзя добавить новый метод в конструктор объектов так же, как добавить новый метод к существующему объекту.

Добавление методов к объекту должно выполняться внутри функции конструктора:

Пример

function Person(firstName, lastName, age, eyeColor) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.eyeColor = eyeColor;
this.changeName = function (name) {
this.lastName = name;
};
}

Функция чанженаме () присваивает значение Name свойству "Фамилия" пользователя.

Объект Math () отсутствует в списке. Математика является глобальным объектом. Ключевое слово New не может использоваться в математике.

Ты знала?

Как вы можете видеть выше, JavaScript имеет версии объектов примитивных типов данных String, number и Boolean. Но нет причин создавать сложные объекты. Примитивные значения намного быстрее.

Используйте литералы объекта {} вместо нового объекта ().

Используйте строковые литералы "" вместо новой строки ().

Используйте числовые литералы 12345 вместо нового числа ().

Используйте логические литералы true/false вместо New Boolean ().

Используйте литералы массива вместо нового массива ().

Используйте шаблонные литералы /()/ вместо нового регулярного выражения ().

Используйте выражения функции () {} вместо новой функции ().

Пример

var x1 = {}; // new object
var x2 = ""; // new primitive string
var x3 = 0; // new primitive number
var x4 = false; // new primitive boolean
var x5 = ; // new array object
var x6 = /()/ // new regexp object
var x7 = function(){}; // new function object

Гибкость Javascript позволяет создавать объекты множеством способов. Но как это нередко случается, разнообразие таит в себе множество подводных камней. Из этой статьи Вы узнаете о том, как разглядеть и обогнуть эти опасные рифы.

Основы основ

Нелишним будет напомнить, что из себя представляют объекты в Javascript и как их можно создавать. Объект в Javascript - это всего лишь хэш-таблица ключей и значений. Если значения представляют собой базовые типы или другие объекты, их называют свойствами , если же это функции, их называют методами объекта.

Объекты, созданные пользователем, можно изменить в любой точке выполнения скрипта. Многие свойства встроенных в язык объектов также изменяемы. То есть можно просто создать пустой объект и добавлять к нему свойства и методы по мере необходимости. Проще всего это сделать с помощью литеральной нотации :
//создаем пустой объект var cat = {}; //добавляем свойство: cat.name = "Garfield"; //или метод: cat.getName = function() { return cat.name; };
Другим способом создания объекта является использование функций-конструкторов:
// литеральная нотация: var cat = {name: "Garfield"}; // конструктор-функция: var cat = new Object(); cat.name = "Garfield";
Очевидно, что литеральная нотация короче конструктора. Есть и философская причина предпочитать литеральную нотацию конструкторам: она подчеркивает, что объект - это всего лишь изменяемый хэш, а не нечто, создаваемое по шаблону, заданному классом.

Кроме того, использование конструктора Object вынуждает интерпретатор проверять, не переопределена ли эта функция в локальном контексте.

Подводный камень конструктора Object

Причин использовать конструктор Object нет. Но все мы знаем, что иногда приходится использовать какой-то старый код, и в этом случае полезно знать об одной особенности этого конструктора. Он принимает аргумент, и в зависимости от его типа может поручить создание объекта другому встроенному в язык конструктору; в итоге мы получим не тот объект, что ожидали:
//пустой объект var o = new Object(); o.constructor === Object; // true var o = new Object(1); o.constructor === Number; //true var o = new Object("string"); o.constructor === String; //true //мы не предполагали, что созданный объект будет иметь этот метод: typeof o.substring; // "function"
Такое поведение конструктора Object может привести к неожиданным результатам, если мы передаем в него значение, неизвестное на этапе выполнения.

Мораль очевидна: не используйте конструктор Object .

Собственные конструкторы

Мы можем определять собственные конструкторы. Использование их выглядит так:
var cat = new Cat("Garfield"); cat.say(); // "I am Garfield"
Синтаксис похож на конструктор Java, но в Javascript конструктор является обычной функцией и поэтому определяется так:
var Cat = function(name) { this.name = name; this.say = function() { return "I am" + this.name; } }
При вызове этого конструктора с оператором new внутри функции происходит следующее:
  • создается пустой объект, на который указывает переменная this ; этот объект наследует прототип функции;
  • к объекту, хранимому в this , добавляются свойства и методы;
  • объект, хранимый в this , неявно возвращается в конце функции (т.к. мы ничего не возвращали явно).
Простоты ради в примере метод say() добавлен к объекту this . Это не очень хорошо, так как каждый раз при вызове new Person() в памяти будет создаваться новая функция. Так как метод say() одинаков для всех объектов, создаваемых с помощью этого конструктора, лучше добавить его к прототипу Cat:
Cat.prototype.say = function() { return "I am " + this.name; };
Кроме того, не совсем корректно утверждать, что объект this , неявно создаваемый в конструкторе, пуст: он наследуется от прототипа Cat , однако рассмотрение прототипов выходит за рамки этой статьи.

Что возвращает конструктор

При использовании оператора new , конструктор всегда возвращает объект. По умолчанию, это объект, на который ссылается this . Конструктор возвращает this неявно, однако мы можем явно вернуть любой другой объект, например:
var Cat = function() { this.name = "I am Garfield"; var that = {}; that.name = "I am Cat-woman"; return that; }; var cat = new Cat(); cat.name // "I am Cat-woman"
Таким образом, мы можем вернуть из конструктора любое значение, но лишь при условии, что это объект. Если мы попытаемся вернуть, скажем, строку или false , это не приведет к ошибке, но оператор возврата будет проигнорирован, и конструктор вернет this .

Коварный new

Конструкторы - это всего лишь функции, вызываемые с оператором new . Что случится, если забыть этот оператор? Интерпретатор не выдаст предупреждений, но это приведет к логическим ошибкам. Переменная this будет указывать не на объект, унаследованный от прототипа конструктора, а на глобальный объект (window в случае браузера):
function Cat() { this.name = "Garfield"; } // новый объект var cat = new Cat(); typeof cat; // "object" cat.name; // "Garfield" //забываем new: var cat = Cat(); typeof cat; // "undefined" window.name; // "Garfield"
В строгом режиме стандарта ECMAScript 5 this в этом случае не будет указывать на глобальный объект. Посмотрим, как можно избежать этой ошибки, если ECMAScript 5 недоступен.
Соглашения об именовании функций
Самым простым способом является неукоснительное соблюдение соглашений об именовании функций: начинаем обычные функции со строчной буквы (myFunction()), а функции-конструкторы - с заглавной (MyConstruction()). К сожалению, такой способ почти ни от чего не спасает.
Явный возврат объекта
Конструкторы могут возвращать любые объекты. Программисты могут воспользоваться этим:
function Cat() { var that = {}; that.name = "Garfield"; return that; }
Имя переменной that выбрано произвольно, это не часть спецификации. С тем же успехом мы можем назвать возвращаемый объект me или self или как Вам заблагорассудится.

Для простых объектов, вроде создаваемого в примере, мы можем вообще обойтись без дополнительных переменных, используя литеральную нотацию:
function Cat() { return { name: "Garfield" }; }
Такой конструктор будет всегда возвращать объект, независимо от того, как его вызывать:
var first = new Cat(), second = Cat(); first.name; // "Garfield" second.name; // "Garfield"
У этого способа есть серьезный недостаток: объект не наследует прототип конструктора, то есть методы и свойства, добавленные непосредственно к Cat , будут недоступны создаваемым с его помощью объектам.

Самовызывающий конструктор
Для решения этой проблемы достаточно проверить, является ли this в теле конструктора экземляром этого самого конструктора, и если нет, вызывать себя снова, но на этот раз с оператором new . Звучит страшно, но на деле просто:
function Cat() { if (!(this instanceof Cat)) { return new Cat(); } this.name = "Garfield"; } Cat.prototype.meow = "Meow!"; var first = new Cat(), second = Cat(); first.name; // "Garfield" second.name; // "Garfield" first.meow; // "Meow!" second.meow; // "Meow!"
Если наш конструктор будет в дальнейшем переименован, придется править его тело. Избежать этого можно проверкой arguments.callee вместо имени конструктора:
if (!(this instanceof arguments.callee)) { return new arguments.callee(); }
Здесь мы воспользовались тем, что внутри каждой функции создается объект arguments , содержащий все параметры, передаваемые функции в момент вызова. Свойство callee этого объекта указывает на вызываемую функцию. Но и здесь нужно проявить осторожность: строгий режим ECMAScript 5 вызывает исключение TypeError при обращении к этому свойству, поэтому стоит заранее сделать выбор между удобством рефакторинга и светлым завтра.

Вместо заключения

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

контент переехал из сниппетов в статьи

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

Существуют встроенные конструкторы javascript, например: Array() , Date() , RegExp() . Стоит отметить: конструктор Object() создает пустой объект, что равнозначно использованию литерала объекта {} .

Прототип – это значение свойства prototype функции конструктора. Каждая функция имеет свойство prototype , данное свойство ссылается на предопределенный объект-прототип. Этот объект работает только в том случае, если функция используется как конструктор, то есть совместно с оператором new.

Каждый объект имеет свойство constructor ; это свойство ссылается на функцию-конструктор, которая, как говорилось выше, выполняет инициализацию свойств объекта.

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

Классы javascript

Javascript не поддерживает классы как таковые. Однако вы можете создавать псевдоклассы, используя функции-конструкторы и прототипы объектов. Конструктор – это класс.

Назначение конструктора - создать новый объект, установить и возвратить его в качестве значения конструктора.

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

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

// объект var opa = {}; var opa_ = {x:0, y:"yes"} var D = new Date(); // текущая дата /* Свойство constructor */ document.write(D.constructor); // function Date() { } D.constructor == Date // true // определяем конструктор: function example_constr(r,t) { this.ad = r; this.ak = t; // метод, но лучше определить как св-во прототипа /* this.r_method = function () { this.qu = this.ad - this.ak; }*/ // метод, но внутри метода не используем свойства объекта this.a_method = function (x,y) { alert(x+y); } } // объявляем метод (r_method) в прототипе // это предпочтительнее, чем использовать r_method в ф-и конструкторе // по причине того, что ф-я r_method не имеет уникальных св-в, в отличие // от вышеприведенных свойств (ad,ak) example_constr.prototype.r_method = function () { this.qu = this.ad - this.ak; } // вызываем конструктор и создаем объект example_constr (krot) var krot = new example_constr(14,15); // что равнозначно krot = {ad:14,ak:15} krot.r_method(); // выведет: //alert(krot.qu); // -1 //krot.a_method(11,11); // выведет: // 22

Дополнение:
Чтобы создать собственный конструктор, достаточно описать функцию, в которой ключевое слово this будет ссылаться на объекты (которые создаются посредством функции конструктора). Смотрите выше на примере example_constr .

console.dir

js

console.dir(obj); // выведет все свойства объекта в консоли

Объекты в javascript позволяют воссоздать концепцию объектно-ориентированного программирования

Для того чтобы создавать объекты одного типа используют функции-конструкторы. Отличие конструктора от обычной функции в том, что конструктор вызывается через специальный оператор new .

При использовании new в функции-конструкторе return может вернуть только объект, причем этот объект заменит возвращаемый по умолчанию объект this .

Приватные переменные и функции

У функции-конструктора могут быть как приватные данные (такие данные внешний код может получить, но изменить не может), так и публичные.

javascript

// определяем конструктор: function example_constr(r,t,name) { // this = {} создается автоматически this.ad = r; this.ak = t; this.a_method = function (x,y) { alert(x+y); } // функция-конструктор и без всякого return // возвращает объект this // приватная переменная (то есть из внешнего кода ее можно получить, // но нельзя изменить): this.getName = function(){ return name; } // также можно использовать обычные переменные, // которые будут доступны в лишь пределах функции-конструктора: var page, password; var ogo = function(){ //................ }; } var newObj = new example_constr(1,2,"Вася"); console.dir(newObj); console.log(newObj.getName()); //

знать

  • ОБЪЕКТЫ javascript работают только со строковыми свойствами, то есть, если свойство не указано как строка, то оно все равно станет строкой.

Последнее обновление: 27.03.2018

Кроме создания новых объектов JavaScript предоставляет нам возможность создавать новые типы объектов с помощью конструкторов . Так, одним из способов создания объекта является применение конструктора типа Object:

Var tom = new Object();

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

Конструктор позволяет определить новый тип объекта. Тип представляет собой абстрактное описание или шаблон объекта. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке - наличие двух рук, двух ног, головы, пищеварительной, нервной системы и т.д. Есть некоторый шаблон - этот шаблон можно назвать типом. Реально же существующий человек является объектом этого типа.

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

Для начала определим конструктор:

Function User(pName, pAge) { this.name = pName; this.age = pAge; this.displayInfo = function(){ document.write("Имя: " + this.name + "; возраст: " + this.age + "
"); }; }

Конструктор - это обычная функция за тем исключением, что в ней мы можем установить свойства и методы. Для установки свойств и методов используется ключевое слово this :

This.name = pName;

В данном случае устанавливаются два свойства name и age и один метод displayInfo.

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

После этого в программе мы можем определить объект типа User и использовать его свойства и методы:

Var tom = new User("Том", 26); console.log(tom.name); // Том tom.displayInfo();

Чтобы вызвать конструктор, то есть создать объект типа User, надо использовать ключевое слово new .

Подобным образом мы можем определить и другие типы и использовать их вместе:

// конструктор типа Car function Car(mName, mYear){ this.name = mName; this.year = mYear; this.getCarInfo = function(){ document.write("Модель: " + this.name + " Год выпуска: " + this.year + "
"); }; }; // конструктор типа User function User(pName, pAge) { this.name = pName; this.age = pAge; this.driveCar = function(car){ document.write(this.name + " ведет машину " + car.name + "
"); }; this.displayInfo = function(){ document.write("Имя: " + this.name + "; возраст: " + this.age + "
"); }; }; var tom = new User("Том", 26); tom.displayInfo(); var bently = new Car("Бентли", 2004); tom.driveCar(bently);

Оператор instanceof

Оператор instanceof позволяет проверить, с помощью какого конструктора создан объект. Если объект создан с помощью определенного конструктора, то оператор возвращает true:

Var tom = new User("Том", 26); var isUser = tom instanceof User; var isCar = tom instanceof Car; console.log(isUser); // true console.log(isCar); // false

Function Person(first, last, age, eye) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eye; }

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

Объектные типы (Шаблоны) (Классы)

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

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

Для создания "объектного типа" и используется функция конструктора объекта .

В приведенном в начале этой главы примере функция Person() является функцией конструктора объекта.

Объекты одного и того же типа создаются при помощи вызова функции конструктора с ключевым словом new :

Var myFather = new Person("John", "Doe", 50, "blue"); var myMother = new Person("Sally", "Rally", 48, "green");

Ключевое слово this

В JavaScript ключевое слово this обозначает объект, которому "принадлежит" данный код.

Значением ключевого слова this , когда оно используется в объекте, является сам объект.

В функции конструктора у ключевого слова this нет значения. Это "подстановка" для нового объекта. Когда будет создан новый объект, тогда значением ключевого слова this и станет этот новый объект.

Обратите внимание, что this это не переменная, а ключевое слово. Вы не можете изменять его значение.

Добавление свойства к объекту

Добавить новое свойство к существующему объекту очень просто:

MyFather.nationality = "English";

Свойство будет добавлено к объекту myFather, но не к объекту myMother. (Или какому-либо другому объекту типа person).

Добавление метода к объекту

Добавить новый метод к существующему объекту очень просто:

MyFather.name = function () { return this.firstName + " " + this.lastName; };

Метод будет добавлен к объекту myFather, но не к объекту myMother. (Или какому-либо другому объекту типа person).

Добавление свойства к конструктору объекта

Нельзя добавлять новое свойство к конструктору объекта тем же способом, как это делается в случае с существующим объектом.

Чтобы добавить новое свойство к конструктору, вы должны добавить его в функцию конструктора:

Function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; this.nationality = "English"; }

При этом свойствам объекта можно устанавливать значения по умолчанию.

Добавление метода к конструктору объекта

Функция конструктора также может определять методы:

Function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; this.name = function() {return this.firstName + " " + this.lastName;}; }

Нельзя добавлять новые методы к конструктору объекта тем же способом, как это делается в случае с существующим объектом. Добавление методов к объекту должно происходить внутри функции конструктора:

Function Person(firstName, lastName, age, eyeColor) { this.firstName = firstName; this.lastName = lastName; this.age = age; this.eyeColor = eyeColor; this.changeName = function (name) { this.lastName = name; }; }

Функция changeName() присваивает значение параметра name свойству lastName объекта person:

MyMother.changeName("Doe");

JavaScript знает, о каком объекте идет речь, "подставляя" в ключевое слово this объект myMother .

Встроенные конструкторы JavaScript

В JavaScript есть встроенные конструкторы для собственных объектов:

Var x1 = new Object(); // Новый объект Object var x2 = new String(); // Новый объект String var x3 = new Number(); // Новый объект Number var x4 = new Boolean(); // Новый объект Boolean var x5 = new Array(); // Новый объект Array var x6 = new RegExp(); // Новый объект RegExp var x7 = new Function(); // Новый объект Function var x8 = new Date(); // Новый объект Date

В этом списке нет объекта Math(), так как это глобальный объект. Ключевое слово new нельзя использовать с объектом Math.

А вы знали?

Как видно из приведенного выше кода, в JavaScript есть объектные версии примитивных типов данных String, Number и Boolean. Однако нет никаких причин создавать для этих типов комплексные объекты. Примитивные значения работают быстрее.

Таким образом:

  • используйте объектные литералы { } вместо new Object().
  • используйте строковые литералы "" вместо new String().
  • используйте числовые литералы 12345 вместо new Number().
  • используйте логические литералы true / false вместо new Boolean().
  • используйте литералы-массивы вместо new Array().
  • используйте литералы-шаблоны /()/ вместо new RexExp().
  • используйте выражения функций () {} вместо new Function().
var x1 = {}; // новый объект Object var x2 = ""; // новая примитивная строка var x3 = 0; // новое примитивное число var x4 = false; // новое примитивное логическое значение var x5 = ; // новый объект Array var x6 = /()/ // новый объект RegExp var x7 = function(){}; // новый объект Function