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

JavaScript предоставляет разработчикам возможность создавать объекты и работать с ними. Для этого существуют следующие приёмы:

  • Оператор new
  • Литеральная нотация
  • Конструкторы объектов
  • Ассоциативные массивы

Используем оператор new

Это, наверное, самый легкий способ создания объекта. Вы просто создаете имя объекта и приравниваете его к новому объекту Javascript.

//Создаем наш объект var MyObject = new Object(); //Переменные MyObject.id = 5; //Число MyObject.name = "Sample"; //Строка //Функции MyObject.getName = function() { return this.name; }

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

//Используем наш объект alert(MyObject.getName());

Литеральная нотация

Литеральная нотация является несколько непривычным способом определения новых объектов, но достаточно легким для понимания. Литеральная нотация работает с версии Javascript 1.3.

//Создаем наш объект с использованием литеральной нотации MyObject = { id: 1, name: "Sample", boolval: true, getName: function() { return this.name; } }

Как видите, это довольно просто.

Объект = { идентификатор: значение, ... }

И пример использования:

Alert(MyObject.getName());

Конструкторы объектов

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

Function MyObject(id, name) { }

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

Var MyFirstObjectInstance = new MyObject(5,"Sample"); var MySecondObjectInstace = new MyObject(12,"Othe Sample");

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

Как и в ООП, у MyObject могут быть методы и различные свойства. Свойствам можно присвоить значения по умолчанию, либо значения, переданные пользователем в конструкторе объекта.

Function MyObject(id, name) { //Значения переданные пользователем this._id = id; this._name = name; //Значение по умолчанию this.defaultvalue = "MyDefaultValue"; }

Аналогичным образом мы можем создавать и функции.

Function MyObject(id,name) { this._id = id; this._name = name; this.defaultvalue = "MyDefaultValue"; //Получение текущего значения this.getDefaultValue = function() { return this.defaultvalue; } //Установка нового значения this.setDefaultValue = function(newvalue) { this.defaultvalue = newvalue; } //Произвольная функция this.sum = function(a, b) { return (a+b); } }

Ассоциативные массивы

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

Var MyObject = new Number(); MyObject["id"] = 5; MyObject["name"] = "SampleName";

Для обхода таких объектов можно использовать такой цикл:

For (MyElement in MyObject) { //Код обхода //В MyElement - идентификатор записи //В MyObject - содержание записи }

По материалу подготовлена небольшая схема.

Вы можете её посмотреть в форматах.

Последнее обновление: 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 , при использовании в объекте, является сам объект.

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

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

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

Пример

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

Сразу после того, как мы создали функцию, у нее есть свойство prototype , куда записан некоторый объект:

Var Foo = function() {} alert(Foo.prototype) //

Правда, это свойство как тот суслик, который есть несмотря на то, что его не видишь:

Var Foo = function() {} Foo.prop = "ololo"; for (var i in Foo) { alert("Foo."+i + " = " + Foo[i]) } // выведет "Foo.prop = ololo" // и НЕ выведет никакого Foo.prototype

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

Var Foo = function() {} for (var i in Foo.prototype) { alert("Foo.prototype."+i + " = " + Foo.prototype[i]) } alert("КОНЕЦ!") // покажет только "КОНЕЦ!"

На самом деле в нем тоже сидит невидимый суслик, в виде свойства Foo.prototype.constructor, куда записана ссылка на саму функцию:

Function Foo() {} alert(Foo.prototype.constructor === Foo) // true

Когда же может пригодиться свойство Foo.prototype? Тогда, когда Foo используется в качестве конструктора, то есть с оператором new. Конструктор создает объекты, все это знают. В JavaScript это тоже так, но логика создания слегка запутанная. Вот перед нами простой с виду код:

Var Foo = function() {} var a = new Foo; alert(a)

Любой пыхарь с уверенностью скажет "Мы создали объект а, являющийся экземпляром класса Foo". На самом деле в 7 символах "new Foo " заключена следующая магия:

  1. Мы создаем пустой объект (как если бы написали a = {} )
  2. Прототипом этого объекта назначается то, что сидит в Foo.prototype
  3. Этот объект привязывается к this в теле Foo
  4. Исполняется функция Foo
  5. Оператор new возвращает созданный объект, если Foo не вернула что-либо другое.

"Прототип" из пункта 2 - это такой объект, где будут искаться свойства созданного объекта a , которые он сам в явном виде не содержит. Код ниже иллюстрирует все это более развернуто:

Var Foo = function() { alert("я - фу!") this.prop = "lol" } // добавляем свойство к Foo.prototype Foo.prototype.bar = "trololo" var a = new Foo // исполняется Foo, видим алерт "я - фу" // в переменную a записывается созданный объект // когда Foo исполнялась, this указывало на него alert(a.prop) // например, через this-ссылку мы добавили свойство prop alert(a.bar) // а свойство bar берется из прототипа

ОК, вроде разобрались, что такое "прототип объекта", откуда он берется и зачем нужен. А как его посмотреть? В идеальном мире мы могли бы обратиться к obj.prototype и получить прототип объекта. Но увы, как мы видели выше, свойство с таким названием используется иначе - хранит то, что функция-конструктор сделает прототипом объекта. Напрашивается вывод, что можно получить прототип через .prototype конструктора. Попробуем:

Var Foo = function() {} Foo.prototype.prop = "ololo" var a = new Foo() alert(a.prop); // берем из прототипа неявно alert(a.constructor.prototype.prop); // а теперь - явно!

Вроде бы работает. Но что, если мы пытались изобразить наследование, расширив Foo другим "классом"?

Function Foo() {} function Bar() { this.prop = "ololo" } Foo.prototype = new Bar // типа наследуемся var a = new Foo alert(a.prop) // работает alert(a.constructor.prototype.prop) // undefined - ой:(// а кстати, что у нас в a.constructor? alert(a.constructor) // Bar!

Самое время задуматься, куда, собственно, указывает a.constructor. А, собственно, никуда не указывает, потому что у a нету такого свойства, оно берется из цепочки прототипов. В примере выше "прототип a" - это экземпляр Bar (потому что в Foo.prototype результат выполнения new Bar). У экземпляра Bar тоже нету свойства constructor. Зато оно есть у прототипа экземпляра Bar - потому что Bar.prototype (прототип экземпляра Bar) имеет свойство.constructor, указывающее на Bar ("свойство-суслик", о котором я писал в самом начале).

Если подумать, факап в этом примере случился из-за того, что мы "расширили" "класс" "экземпляром" (да, все - в кавычках!). Логичнее "расширять" "класс" "классом", но сути это не меняет - на obj.constructor.prototype в поисках прототипа мы полагаться не можем. Потому что obj.constructor - это не "функция, создавшая obj", а в лучшем случае - "функция, создавшая прототип obj" (так сформулировано в ). В лучшем случае - потому что, вообще-то, там может быть что угодно:

// "Класс", создающий компанию с ключевыми сотрудниками function Company (team) { for (var profession in team) { this = team } } var AvtoVAZ = new Company({ president:"Игорь Комаров", constructor:"Сергей Кудрюк " // главный конструктор АвтоВАЗа }) alert(AvtoVAZ.constructor) // упаси Бог пытаться создать новую компанию так: // var KAMAZ = new AvtoVAZ.constructor()

В общем, догадаться самостоятельно не получается, надо лезть в доки, маны и прочую матчасть. Там мы обнаруживаем совершенно курьезную ситуацию: JavaScript, прототипно-ориентированный язык, обзавелся нормальным способом получения прототипа только на 14-м году своей жизни, в версии 1.8.1! Этот способ называется Object.getPrototypeOf() и не поддерживается IE младше 9.

Function Foo() {} function Bar() { this.prop = "boo" } var b = new Bar Foo.prototype = b var a = new Foo // получаем прототип var aproto = Object.getPrototypeOf(a) alert(aproto.prop) // boo из экземпляра Bar // меняем в прототипе aproto.prop = "woo" alert(a.prop) // woo - "меняется" и в экземпляре // меняем в прототипе неявно b.prop = "zoo" alert(a.prop) // zoo - работает! // потому что Foo.prototype, aproto и b - все указывают на один и тот же объект

До появления этой штуки у разработчиков было только свойство.__proto__, которое работает только в Mozilla-образных браузерах.

Function Foo() {} var proto = {prop:"woo"} Foo.prototype = proto var a = new Foo alert(a.__proto__.prop) // свойство есть в прототипе proto.prop = "zoo" alert(a.__proto__.prop) // поменяли прототип, отразилось на экземпляре a.__proto__.prop = "boo" alert(proto.prop) // и в обратную сторону работает

Настало время для типа-саммари.

Что такое "прототип объекта obj"?
Это объект, к которому JS обращается за свойствами, которых нету у самого obj.

Что такое obj.prototype?
Если obj - это функция, то obj.prototype - то, что станет прототипом объекта при вызове new obj().


Что такое obj.constructor?
Если очень повезет - ссылка на функцию, создавшую obj, или прототип obj. А так вообще - что угодно:)

Что такое obj.__proto__?
Это прототип объекта obj, если у вас мозилла

Что такое Object.getPrototypeOf(obj)
Это способ получить ссылку на прототип объекта obj, который станет кроссбраузерным после смерти IE8 (ну FF до 3.5)

Зачем мне все это знать? о_0
Если создание сайтов - ваша работа, то... вам это все знать нафиг не нужно:) Если только для общей образованности, ну и чтоб голову поломать на досуге.

The constructor method is a special method for creating and initializing an object created within a class .

The source for this interactive example is stored in a GitHub repository. If you"d like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

Syntax

constructor([arguments ]) { ... }

Description

There can be only one special method with the name "constructor" in a class. Having more than one occurrence of a constructor method in a class will throw a SyntaxError error.

Class Square extends Polygon { constructor(length) { // Here, it calls the parent class" constructor with lengths // provided for the Polygon"s width and height super(length, length); // Note: In derived classes, super() must be called before you // can use "this". Leaving this out will cause a reference error. this.name = "Square"; } get area() { return this.height * this.width; } set area(value) { this.area = value; } }

Another example

Take a look at this code snippet

Class Polygon { constructor() { this.name = "Polygon"; } } class Square extends Polygon { constructor() { super(); } } class Rectangle {} Object.setPrototypeOf(Square.prototype, Rectangle.prototype); console.log(Object.getPrototypeOf(Square.prototype) === Polygon.prototype); //false console.log(Object.getPrototypeOf(Square.prototype) === Rectangle.prototype); //true let newInstance = new Square(); console.log(newInstance.name); //Polygon

Here the prototype of Square class is changed but still the constructor of the previous base class Polygon is called when a new instance of a square is being created.

Default constructors

As stated, if you do not specify a constructor method a default constructor is used. For base classes the default constructor is:

Constructor() {}

For derived classes, the default constructor is:

Constructor(...args) { super(...args); }

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
The definition of "Constructor Method" in that specification.
Draft

Browser compatibility

The compatibility table on this page is generated from structured data. If you"d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
constructor Chrome Full support 49

Notes

Full support 49

Notes

Notes
Edge Full support 13 Firefox Full support 45 IE No support No Opera Full support 36 Safari Full support 9 WebView Android Full support 49

Notes

Full support 49

Notes

Notes From Chrome 42 to 48 strict mode is required. Non-strict mode support can be enabled using the flag "Enable Experimental JavaScript".
Chrome Android Full support Yes Firefox Android Full support 45 Opera Android ? Safari iOS Full support 9 Samsung Internet Android Full support Yes nodejs Full support 6.0.0 Full support 6.0.0 Full support 4.0.0