-
Notifications
You must be signed in to change notification settings - Fork 16
Object.create
С помощью оператора instanceof строится логическое выражение, которое принимает значение true, если объект является экземпляром класса:
[объект] instanceof [класс]Этот метод использовался для доступа к прототипу объекта до того, как в спецификации ES6 ( 2015 ) появилось свойство __proto__
Создает экземпляр объекта на основе прототипа
Методу нужно передать в качестве первого аргумента ссылку на прототип, который будет использован при создании экземпляра
Вторым ( опциональным ) аргументом может быть объект-дескриптор свойств создаваемого экземпляра
var figure = {
className: "Figure"
}
var circle = Object.create ( figure )Если передать null в качестве аргумента, будет создан объект без прототипа:
var emptyObject = Object.create ( null )Метод Object.create() позволяет задавать дескрипторы свойств объекта
( как это делает метод Object.defineProperty(), который добавляет свойство в объект )
function Figure ( figType ) {
this.type = figType
console.log ( "Instance of Figure created" )
}
Figure.prototype.className = "Figure"
var circle = Object.create ( new Figure ( "circle" ), {
x: {
value: undefined,
writable: true,
configurable: false,
enumerable: false
},
y: {
value: undefined,
writable: true,
configurable: false,
enumerable: false
},
radius: {
value: undefined,
writable: true,
configurable: false,
enumerable: false
}
})Выведем в консоль переменную circle:
▼ Figure {x: undefined, y: undefined, radius: undefined}
radius: undefined
x: undefined
y: undefined
▼ __proto__: Figure
type: "circle"
▼ __proto__:
className: "Figure"
► constructor: ƒ Figure( figType )
► __proto__: Objectcircle instanceof Figure // trueСоздадим экземпляр объекта proto:
var proto = {
figure: "circle",
size: 100,
clip: false,
changeFigure: function ( newFigure ) {
this.figure = newFigure
}
}А теперь вызовем метод Object.create() для создания экземпляра obj:
var obj = Object.create ( proto )В консоли посмотрим на результат:
▼ {}
▼ __proto__:
► changeFigure: ƒ ( newFigure )
clip: false
figure: "circle"
size: 100
► __proto__: ObjectВсе свойства и методы объекта proto, взятого в качестве прототипа, стали унаследованными свойствами и методами экземпляра obj
Теперь создадим простой конструктор:
var Creator = function ( id, val ) {
this.id = id
this.val = val
}и вызовем его как обычную функцию, передав контекст нашего экземпляра obj:
Creator.call ( obj, "sample", 75 )Посмотрим результат в консоли:
Создадим конструктор Human и воспользуемся методом Object.create() для создания нового экземпляра worker:
function Human ( name = "Тимофей", hobby = "футбол" ) {
this.name = name,
this.hobby = hobby
}
Human.prototype = {
speciality: "монтажник",
age: 20
}
var worker = Object.create (
new Human ( "Иван", "рыбалка" )
)Выведем в консоль экземпляр worker:
▼ {}
▼ __proto__:
hobby: "рыбалка"
name: "Иван"
▼ __proto__:
age: 20
speciality: "монтажник"
► __proto__: ObjectА теперь проверим, что worker является экземпляром Human
worker instanceof Human // true
worker instanceof Object // trueОбъявим конструктор класса SuperClass
function SuperClass () {
this.__proto__.type = "SuperClass"
this.__proto__.name = "Родительский класс"
}Теперь используем метод Object.create() для создания подкласса SubClass класса SuperClass
Для этого объявим конструктор подкласса SubClass:
function SubClass () {
SuperClass.call ( this )
this.name = "Дочерний класс"
this.type = "SubClass"
}
// Конструктор SuperClass вызывается
// в конструкторе SubClass
// как обычная функция,
// однако в контексте экземпляра
// ( sample )var sample = new SubClass()Обратите внимание, что SuperClass передал унаследованные свойства экземпляру, но при этом сам не появился в цепочке наследования:
sample instanceof SubClass // true
sample instanceof SuperClass // false
sample instanceof Object // trueВ данном примере SuperClass выполняет функцию декоратора
Объявляем конструктор класса Dishes:
function Dishes ( type ) {
this.type = "Посуда"
console.log ( "Конструктор Dishes создал экземпляр посуды: \n", this )
}Создаем свойства и методы прототипа:
Dishes.prototype.wash = function () {
this.clean = true
console.info ( 'Посуда вымыта' )
}
Dishes.prototype.use = function () {
this.clean = false
console.info ( 'Посуда использована, она грязная' )
}Теперь создадим конструктор класса Cup:
function Cup ( color ) {
this.type = "чашка"
this.color = color || "синяя"
}Нужно сделать так, класс Cup был подклассом класса Dishes
Используем прототип класса Dishes:
Cup.prototype = Object.create ( Dishes.prototype )Для того, чтобы класс Cup унаследовал
собственные перечислимые свойства родительского класса Dishes,
вызовем конструктор класса Dishes
с передачей ему контекста Cup.prototype:
Dishes.call ( Cup.prototype )Создадим экземпляр класса Cup:
var redCup = new Cup ( "красная" )▼ Cup {type: "чашка", color: "красная", clean: true}
clean: true
color: "красная"
type: "чашка"
▼ __proto__: Dishes
type: "Посуда"
▼ __proto__:
► use: ƒ ()
► wash: ƒ ()
► constructor: ƒ Dishes( type )
► __proto__: ObjectИтак, мы построили цепочку прототипов
Для проверки, что наш экземпляр redCup принадлежит одновременно классам Cup и Dishes, воспользуемся оператором instanceof:
redCup instanceof Cup // true
redCup instanceof Dishes // true
greenCup instanceof Object // trueТеперь проверим, как работает наша "машинка"
Мы уже создали экземпляр redCup
Давайте используем чашку, а потом помоем ее
redCup.use ()выдаст в консоль сообщение: Посуда использована, она грязная
redCup.wash ()выдаст в консоль сообщение: Посуда вымыта
Аналогичный результат можно получить значительно проще, используя свойство __proto__
Сейчас мы усложним задачу, удлинив цепочку прототипов еще одним классом - Kitchenware
Создадим конструктор класса Kitchenware:
var Kitchenware = function () {
this.className = "Кухонная утварь"
this.__proto__.constructor = Kitchenware
}Теперь создадим конструктор класса Dishes,
и используем конструктор Kitchenware
для создания прототипа экземпляров класса Dishes:
var Dishes = function () {
this.__proto__ = new Kitchenware ()
this.__proto__.constructor = Dishes
this.className = "Посуда"
}Теперь создадим конструктор класса Cup,
и используем конструктор Dishes
для создания прототипа экземпляров класса Cup:
var Cup = function ( $color ) {
this.__proto__ = new Dishes ()
this.__proto__.constructor = Cup
this.className = "Чашка"
this.color = $color || "белая"
}Теперь создадим экземпляр yellowCup класса Cup и выведем его в консоль:
var yellowCup = new Cup ( "желтая" )
console.log ( '*** cup: ', yellowCup )А также выведем в консоль цепочку прототипов, используя метод Object.getPrototypeOf():
console.log (
'yellowCup prototype: ',
Object.getPrototypeOf ( yellowCup )
)
console.log (
'yellowCup prototype of prototype: ',
Object.getPrototypeOf (
Object.getPrototypeOf ( yellowCup )
)
)Обратите внимание, что ссылка на конструктор задана в явном виде:
this.__proto__.constructor = DishesЭто необходимо потому, что после выполнения присваивания
this.__proto__ = new Kitchenware () имя конструктора прототипа будет Kitchenware, а не Dishes
Из-за этого мы получили бы в консоли вот такую картинку:
Аналогично мы явно указываем ссылку на функцию-конструктор чашки:
this.__proto__.constructor = CupОднако воспользуемся теперь оператором instanceof
yellowCup instanceof Kitchenware // true
yellowCup instanceof Dishes // false
yellowCup instanceof Cup // false
yellowCup instanceof Object // trueКак мы видим, хотя в консоли цепочка прототипов выглядит вполне прилично,
на самом деле произошла передача свойств вместо наследования
• Object.defineProperty()
• Object.defineProperties()
• Object.entries()
• Object.freeze()
• Object.getOwnPropertyDescriptor()
• Object.getOwnPropertyDescriptors()
• Object.getOwnPropertyNames()
• Object.getOwnPropertySymbols()
• Object.getPrototypeOf()
• Object.is()
• Object.isExtensible()
• Object.isFrozen()
• Object.isSealed()
• Object.keys()
• Object.preventExtensions()
• Object.seal()
• Object.setPrototypeOf()
• Object.values()
© 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
Коды символов