Тема 2.3 Прототипное наследование


В программирования часто решаются задачи по расширению возможностей определенного кода (модуля). Например, у нас есть объект user со своими свойствами и методами. На его основе нам надо создать объекты admin и guest, как слегка измененные варианты объекта user. Такую возможность нам может предоставить прототипное наследование.

[[Prototype]]

В JavaScript объекты имеют специальное скрытое свойство [[Prototype]], которое либо равно null, либо ссылается на другой объект. Этот объект называется прототип:

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

Свойство [[Prototype]] является внутренним и скрытым, но его можно задать:

Одном из способов использования конструкции __proto__, например:

let animal = {

eats: true

};

let rabbit = {

jumps: true

};

rabbit.__proto__ = animal;

 

Если мы ищем свойство в rabbit, а оно отсутствует, JavaScript автоматически берет его из animal.

Можно сказать, что animal является прототипом rabbit или rabbit прототипно наследует от animal. Так что если у animal много полезных свойств и методов, то они автоматически становятся доступными у rabbit. Такие свойства называются унаследованными.

let animal = {

eats: true,

walk() {

alert("Animal walk");

}

};

 

let rabbit = {

jumps: true,

__proto__: animal

};

 

// walk взят из прототипа

rabbit.walk(); // Animal walk

 

Прототип используется только для чтения свойств. Операции записи/ удаления работают напрямую с объектом. Присвоим rabbit собственный метод walk:

let animal = {

eats: true,

walk() {

/* этот метод не будет использоваться в rabbit */

}

};

 

let rabbit = {

__proto__: animal

};

 

rabbit.walk = function() {

alert("Rabbit! Bounce-bounce!");

};

 

rabbit.walk(); // Rabbit! Bounce-bounce!

Свойство __proto__ считается устаревшим. На сегодняшний день его заменили методами:

Object.create(proto, [descriptors]) – создает пустой объект со свойством [[Prototype]], указанным как proto, и необязательными дескрипторами свойств descriptors.

Object.getPrototypeOf(obj) – возвращает свойство [[Prototype]] объекта obj.

Object.setPrototypeOf(obj, proto) – устанавливает свойство [[Prototype]] объекта obj как proto.

Рассмотрим на примере:

let animal = {

eats: true

};

 

// создаём новый объект с прототипом animal

let rabbit = Object.create(animal);

 

alert(rabbit.eats); // true

 

// получаем прототип объекта rabbit

alert(Object.getPrototypeOf(rabbit) === animal);

 

// заменяем прототип объекта rabbit на {}

Object.setPrototypeOf(rabbit, {});


У Object.create есть необязательный второй аргумент. Его можно использовать для добавления дополнительных свойств новому объекту:

let animal = {

eats: true

};

 

let rabbit = Object.create(animal, {

jumps: {

value: true

}

});

 

alert(rabbit.jumps); // true

 

 

Тема 2.4 Классы

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

Базовый синтаксис создания класса выглядит следующим образом:

class MyClass {

// методы класса

constructor() { ... }

method1() { ... }

method2() { ... }

method3() { ... }

...

}

Затем используется вызов new MyClass() для создания нового объекта со всеми перечисленными методами. При этом автоматически вызывается метод constructor(), в нем можно инициализировать объект.

class User {

 

constructor(name) {

this.name = name;

}

 

sayHi() {

alert(this.name);

}

}

 

// Использование:

let user = new User("Иван");

user.sayHi();

 

Когда вызывается new User("Иван"):

1. Создается новый объект;

2. Constructor запускается с заданным аргументом и сохраняет его в this.name.

Затем можно вызывать на объекте методы, такие как user.sayHi().

Методы в классе не разделяются запятой!

В JavaScript класс – это разновидность функции. Конструкция class User{…}:

1. Создает функцию с именем User, которая становится результатом объявления класса. Код функции берется из метода constructor;

2. Сохраняет все методы, такие как sayHi, в User.prototype.

При вызове метода объекта new User он будет взят из прототипа. Таким образом, объекты new User имеют доступ к методам класса.

Геттеры/ сеттеры

В классах можно объявлять вычисляемые свойства, геттеры/сеттеры и другие.

Пример user.name, реализованный с использованием get/set:

class User {

 

constructor(name) {

// вызывает сеттер

this.name = name;

}

 

get name() {

return this._name;

}

 

set name(value) {

if (value.length < 4) {

alert("Имя слишком короткое.");

return;

}

this._name = value;

}

 

}

 

let user = new User("Иван");

alert(user.name); // Иван

 

user = new User(""); // Имя слишком короткое.

 



Дата добавления: 2021-01-26; просмотров: 304;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.015 сек.