Всем привет. В сегодняшней статье разберём, что такое Объекты, конструкторы и прототипы в JavaScript . JavaScript очень отличается от других объектно-ориентированных языков программирования, как, например, C++, Java, PHP и т.д. В этих языках используются классы , на основе которых потом создаются объекты . В JavaScr...
Всем привет. В сегодняшней статье разберём, что такое Объекты, конструкторы и прототипы в JavaScript. JavaScript очень отличается от других объектно-ориентированных языков программирования, как, например, C++, Java, PHP и т.д. В этих языках используются классы, на основе которых потом создаются объекты. В JavaScript же классов нет, но есть объекты. Всё кроме null, undefined, string, number, boolean в JavaScript является объектом, поэтому очень важно знать, как они работают. Что же, давайте начнём.
Объект - это набор свойств и методов. Рассмотрим пример:
var person = {};
var person = new Object();
Здесь мы создали пустой объект. 1 и 2 случай идентичны, но первый короче и поэтому используется чаще. Давайте заполним наш объект какими-то свойствами
var person = {
name: 'Alex',
age: 27
};
Слева указывается название свойства, а через двоеточие его значение. Свойства отделяются друг от друга запятой. Теперь мы можем узнать значение свойства, изменить его или добавить новое.
console.log(person.name); // выводит в консоль имя
console.log(person['name']); // аналогично первому случаю
person.age = 30; // изменили свойство age с 27 на 30
person.gender = 'male'; // добавили новое свойство gender со значением male
Здесь всё понятно, но поясню второй способ обращения к свойству. Он используется обычно, когда нужно обратиться к свойству, имя которого записано в переменной. Такое бывает, например, в циклах. Там мы не можем обратиться к свойству через точку, будет ошибка, поэтому мы используем квадратные скобки.
var k = 'name';
console.log(person.k); // Ошибка!
console.log(person[k]); // выведет значение
Если мы попытаемся обратиться к несуществующему свойству, то получим undefined.
console.log(person.height); // Такого свойства нет - undefined
Теперь разберём, что же такое методы.
Методы - это просто функции в объекте.
var person = {
name: 'Alex',
greet: function() {
console.log("Hello! My name is " + this.name);
}
};
В объекте person мы создали метод greet, который выводит в консоль приветствие. This в коде означает текущий объект, т.е. мы могли бы написать person.name и это также прекрасно работало бы, но что если нам нужно, например, поменять имя объекта? Тогда нам пришлось везде бы менять person на новое имя. С использованием this таких проблем нет.
Что такое объект разобрались. Давайте теперь поговорим, что же такое конструктор?
Конструктор - это просто функция, вызывая которую с ключевым словом new, мы получим новый объект. Рассмотрим пример:
var Person = function(name, age) {
this.name = name;
this.age = age;
};
var human = new Person('Alex', 27);
Интепретатор JavaScript видит ключевое слово new и запускает функцию, которая создаёт пустой объект, на который ссылается this. Дальше функция просто присваивает свойствам name и age переданные значения, а затем отдаёт новый объект, на который и передаётся ссылка в переменную human. Да-да! Я не случайно написал ссылка. Дело в том, что все объекты хранятся где-то в памяти, а в переменную попадает лишь ссылка на него, но не он сам.
var a = 5;
var b = 7;
a = b;
console.log(a, b);
В данном примере мы переменной a присваиваем значение переменной b, поэтому в консоль выведется "7 7". Теперь давайте попробуем сделать так же и с объектами
var a = {
name: 'Alex'
};
var b = {
name: 'Bob'
};
a = b;
b.name = "John";
console.log(a.name);
Если вы запустите данный пример, то увидите John, т.к. переменная a и b ссылаются на один и тот же объект.
Теперь давайте поговорим о прототипах. Практически любой объект в JavaScript имеет другой, связанный с ним объект, который и называется прототипом. Объект наследует свойства своего прототипа, или проще говоря, все свойства и методы, которые есть у прототипа будут доступны через наш дочерний объект. Создать их очень просто
var person = {
name: 'Alex'
};
var object = Object.create(person);
console.log(object.name);
В данном примере мы создаём новый объект object, который наследует все свойства от его прототипа person с помощью функции create.
Теперь поговорим о том, зачем нам всё это нужно? Допустим, в вашей программе вам нужно создавать много однотипных объектов
var person = {
name: 'Alex',
age: 27,
greet: function() {
console.log("My name is " + this.name);
}
};
var person2 = {
name: 'John',
age: 17,
greet: function() {
console.log("My name is " + this.name);
}
};
var person3 = {
name: 'Jessica',
age: 37,
greet: function() {
console.log("My name is " + this.name);
}
};
Прописывать все свойства и одинаковые методы в данном случае глупо. Это очень сильно усложнит ваш код и понизит его производительность. Рассмотрим, как сделать правильно
var Person = {
constructor: function(name, age) {
this.name = name;
this.age = age;
return this;
},
greet: function() {
console.log("My name is " + this.name);
}
};
var person, person2, person3;
person = Object.create(Person).constructor("Alex", 27);
person2 = Object.create(Person).constructor("John", 17);
person3 = Object.create(Person).constructor("Jessica", 37);
Наш код стал короче и более производительным. Давайте теперь разберёмся, что же мы сделали. Для начала мы вынесли общий для всех объектов метод greet в прототип Person. Теперь у нас не 3 функции, а только одна, что хорошо скажется на производительности. Значения name и age у нас для всех объектов разные, поэтому мы создали метод constructor, в котором просто написали функцию, которая инициализирует новый объект и возвращает его. Дальше мы создаём новый объект при помощи Object.create() и сразу вызываем его метод constructor, куда передаём данные. Так мы можем создавать сколько угодно новых объектов, обращаться к их свойствам и вызывать их методы.
console.log(person.name); // Alex
console.log(person2.age); // 17
console.log(person3.name); // Jessica
person.greet(); // My name is Alex
person2.greet(); // My name is John
person3.greet(); // My name is Jessica
Класс в языке JavaScript это чисто условное понятие и под классом понимают всего лишь множество всех объектов, которые наследуют свои свойства от одного прототипа. Т.е. в нашем случае эти 3 объекта(person, person2, person3) имеют один класс, потому что они наследуют свойства от одного прототипа.
Для того, чтобы определить является ли объект прототипом другого объекта, есть метод isPrototypeOf
Person.isPrototypeOf(person); // true
Итак, сегодня вы узнали такие основные вещи, как объекты, конструкторы и прототипы. Надеюсь, вы всё поняли, но если всё-таки остались вопросы - оставляйте их в комментариях. До скорого!
