-
Notifications
You must be signed in to change notification settings - Fork 16
Class super
| ⏪ |
|---|
Методы родительского класса доступны в дочернем классе посредством ключевого слова super
Расширим метод drawLine родительского класса,
добавив аргумент lineWidth ( толщину линии )
Для этого определим "расширенный" метод drawLine
внутри дочернего класса,
который будет вызывать метод drawLine
родительского класса
с помощью ключевого слова super:
super.drawLine ( points, lineColor )Теперь код будет таким:
const Canvas = class {
constructor () {
this.canvas = document.createElement ( 'canvas' )
document.body.appendChild ( this.canvas )
this.canvas.style.border = "1px solid #000000"
this.area = this.canvas.getContext ( "2d" )
}
drawLine ( points ) {
this.area.beginPath()
this.area.moveTo( points[0].x, points[0].y )
this.area.lineTo( points[1].x, points[1].y )
this.area.stroke()
}
}
class ExtendedCanvas extends Canvas {
drawLine ( points, lineColor, lineWidth ) {
this.area.lineWidth = lineWidth || 3
this.area.strokeStyle = lineColor
super.drawLine ( points )
}
}Создадим экземпляр дочернего класса:
let newCanvas = new ExtendedCanvas ()и вызовем его метод drawLine
newCanvas.drawLine ( [ { x: 20, y: 20 }, { x: 300, y: 400 } ], "#ffaa00", 10 )Теперь линия будет отрисовываться заданной толщины
В предыдущих примерах мы не использовали конструктор наследующего класса
☝ Когда нужно добавить свойства
экземпляру наследующего класса,
без конструктора это сделать невозможно
✋ Первое, что нужно выполнить в конструкторе наследующего класса - вызвать метод super ()
const Canvas = class {
constructor () {
this.canvas = document.createElement ( 'canvas' )
document.body.appendChild ( this.canvas )
this.area = this.canvas.getContext ( "2d" )
}
drawLine ( points ) {
this.area.beginPath()
this.area.moveTo( points[0].x, points[0].y )
this.area.lineTo( points[1].x, points[1].y )
this.area.stroke()
}
}
class ExtendedCanvas extends Canvas {
constructor () {
super ()
this.history = []
}
}В противном случае будет сгенерировано исключение:
⛔️ Uncaught ReferenceError:
Must call super constructor in derived class before accessing 'this' or returning from derived constructor
Ключевое слово super можно использовать без объявления классов
Он является просто ссылкой на прототип объекта
Поэтому можно использовать его для доступа к свойствам и методам объекта-прототипа
В примерах далее мы будем использовать объекты, объявленные в литеральной форме
В качестве прототипа объекта person будет выступать объект human
Назначать объект human прототипом объекта person мы будем с помощью метода
Object.setPrototypeOf ( person, human )После такого назначения внутри объекта person
свойства и методы объекта human будут доступны
с помощью ключевого слова super
В следующем примере вызовем методы place () и say ()
прототипа human
в методах getPlace () и talk ()
объекта person
с помощью ключевого слова super :
let human = {
place () {
var x = document.createElement ( "p" )
document.body.appendChild ( x )
x.id = "demo"
return x
},
say ( text ) {
this.place.innerHTML = text
}
}
let person = {
getPlace () { this.place = super.place () },
talk ( text ) {
super.say ( text )
}
}
Object.setPrototypeOf ( person, human )
person.getPlace ()
person.talk ( "привет!" )✍ В этом примере метод place() прототипа ( объекта human )
проверяет наличие элемента с id === "demo",
и если такой элемент найден,
возвращает ссылку на него,
в противном случае создает такой элемент,
добавляет его на страницу и возвращает ссылку на него
✍ Объект person изначально не имеет свойства place,
но имеет собственный метод getPlace (),
который создает такое свойство,
вызывая с помощью ключевого слова super
метод place() прототипа ( объекта human ),
и присваивая возвращенное этим методом
значение собственному свойству place
✍ Метод talk( text ) объекта person
вызывает метод getPlace()
до вызова метода say ()
прототипа ( объекта human )
let human = {
place: () =>
document.getElementById ( "demo" ) ?
document.getElementById ( "demo" ) :
document.body.appendChild (
document.createElement ( "p" )
).id = "demo",
say ( text ) {
this.place.innerHTML = text
}
}
let person = {
getPlace () { this.place = super.place() },
talk ( text ) {
this.getPlace ()
super.say ( text )
}
}
Object.setPrototypeOf ( person, human )
person.talk ( "привет!" )
setTimeout ( () => person.talk ( "Hello, baby!" ), 2000 )☝ Обратите внимание,
что при объявлении метода place() объекта human
мы использовали стрелочную функцию,
а при объявлении метода say ее использовать нельзя,
поскольку внутри методов,
объявленных с помощью стрелочных функций,
контектом вызова будет глобальный объект window
В этом примере свойство place прототипа ( объекта human )
уже не является методом
Его значение ( ссылка на элемент )
будет установлено при инициализации объекта human
В этом примере демонстрируется взаимозаменяемость
ключевых слов super и this
при ссылках на свойства прототипа
👉 Метод talk() объекта person
вызывает метод say () прототипа
без ключевого слова super
( с ключевым словом this )
👉 Когда метод say() в объекте person не будет найден,
поиск будет продолжен в прототипе,
где и будет благополучно найден
👉 Внутри метода say(), вызванного из метода talk(),
контекстом вызова будет объект person
( т.е. this будет указывать на объект person )
но тем не менее ссылка this.place
будет благополучно разрешена по цепочке прототипов
let human = {
place: ( () => {
if ( document.getElementById ( "demo" ) )
return document.getElementById ( "demo" )
var x = document.body.appendChild (
document.createElement ( "p" )
)
x.id = "demo"
return x
})(),
say ( text ) {
this.place.innerHTML = text
}
}
let person = {
talk ( text ) {
this.say ( text )
}
}
Object.setPrototypeOf ( person, human )
person.talk ( "привет!" )
setTimeout ( () => person.talk ( "Hello, baby!" ), 2000 )👉 Если же имена свойств объекта и его прототипа совпадают,
и нужно вытянуть именно свойство прототипа,
а не собственное свойство объекта,
то для унаследованных свойств можно использовать __proto__
let person = {
say ( text ) { console.log ( text ) },
talk ( text ) {
this.__proto__.say ( text )
}
}👉 Очевидно, в таком случае код:
super.say ( text )короче, чем
this.__proto__.say ( text )а результат идентичный 😉
👉 В этом примере мы используем геттеры и сеттеры свойств объектов
Для вычисляемых свойств это наиболее корректный способ доступа к их значениям
let human = {
id: "",
get place () {
if ( this.id ) return document.getElementById ( this.id )
},
set place ( newId ) {
this.id = newId
if ( document.getElementById ( this.id ) ) return
var x = document.createElement ( "p" )
document.body.appendChild ( x )
x.id = this.id
},
get message () {
return this.place.innerHTML
},
set message ( val ) {
this.place.innerHTML = val
}
}
let person = {
talk ( text ) {
super.message = text
},
get place () {
return super.place
},
set place ( newId ) {
super.place = newId
}
}
Object.setPrototypeOf ( person, human )
person.place = "demo"
person.talk ( "привет!" )
setTimeout ( () => person.talk ( "Hello, baby!" ), 2000 )| ⏪ |
|---|
© Irina H.Fylyppova 2018
Использование данных материалов или любой их части коммерческими школами ( курсами ) является нарушением авторских прав
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 |
| ⏬ |
|---|
- Блок-схема алгоритма
- Developer Tools
- Chrome DevTools
- Переменные
- Оператор typeof
- Структуры данных
- Операторы присваивания
- Логические выражения
- Условные операторы
- Инкремент
- Свойство length
- Оператор цикла for
- UTF-8
Homework
- Приведение типов
- NaN | null | Infinity
- BigInt (ES10)
- Функции
- Методы
- Методы строк
- Методы массивов
- Date ()
Самостоятельная работа
Практика (XSS)
Homework
- Циклы while и do...while
- Циклы for...of и for...in
- Параметры по умолчанию
- Объект function
Практика
Homework
- Нативные и host-объекты
- Литерал объекта
- Унаследованные свойства
- Конструктор
- Модель наследования
- Публичные и приватные свойства
- Оператор in
1
Homework
- Итерирующие методы массивов
- Тестирование производительности
- SHA
Homework
- Размеры и прокрутка элемента
- Event Loop
- async | await
- API
- REST | HATEOAS
- status codes
JSON placeholder-
JSON server
fake chat
Homework
- strict mode
- Вычисляемые имена свойств
- Краткий синтаксис методов
- Краткий литерал объекта
- Классы
Homework
- :not(:defined)
- Shadow DOM
- Custom elements
- Lifecycle hooks
- whenDefined
- <template>
- slot
1
2
3
Homework
- npm
- webpack
Упражнение 1- ES6 модули
Упражнение 2- --mode | --watch
Упражнение 3
Упражнение 4
Упражнение 5
Упражнение 6
Упражнение 7
Упражнение 8
Homework
| ⏫ |
|---|

Дополнительно
Справочная инфо
Git Bush
TCP/IP
Коды символов