Объекты, прототипы и конструкторы в языке JavaScript.
Всем привет. В сегодняшней статье мы разберём, что такое Объекты, конструкторы и прототипы в 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
Итак, сегодня вы узнали такие основные вещи, как объекты, конструкторы и прототипы. Надеюсь, вы всё поняли, но если всё-таки остались вопросы - оставляйте их в комментариях. До скорого!
-
- Михаил Русаков
Комментарии (6):
String, Number и Boolean также являются объектами. Например: var x = new Number(55.888); console.log(x.toFixed(1)); // 55.9 console.log(x.toString()); // "55.888"
Ответить
Михаил, поставьте на комментарии nl2br(), а то лепится все в одну строчку
Ответить
String, Number и Boolean не являются объектами. Это простые типы: строка, число, логический тип. То, что Вы показали, это так называемые объекты-обёртки, которые облегчают нам некоторые задачи. Например, если Вы напишите вот так: var str = "привет"; str = str.toUpperCase(); document.write(str); То интерпретатор, увидев метод toUpperCase() на лету сделает из простого типа объект, применит данный метод, т.е. приведёт все буквы к верхнему регистру, а потом обратно преобразует в ПРОСТОЙ ТИП строка. Данные понятия путать не стоит.
Ответить
Не простой тип, а примитив. String, Number и Boolean являются примитивом без использования new, а с new это уже объект. Number(), String(), Boolean() - это лишь функции обертки. А то что без new это примитив доказывает этот код: var str = ‘str’; str.test = ‘test’; //ошибки не будет, программа продолжит работать, но console.log(str.test); //undefined
Ответить
Простой тип и примитив - это синонимы. А то, что вы описали дальше, следует из моего комментария.
Ответить
А что такое console.log? Вы об этом не писали, объясните пожалуйста подробнее или напишите статью.
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.