Skip to content

Object.create

garevna edited this page Jun 16, 2019 · 12 revisions

🎓 Статические методы конструктора Object


Object.assign()


🎓 instanceof

С помощью оператора instanceof строится логическое выражение, которое принимает значение true, если объект является экземпляром класса:

[объект]  instanceof  [класс]

🎓 Object.create()

Этот метод использовался для доступа к прототипу объекта до того, как в спецификации ES6 ( 2015 ) появилось свойство __proto__

Создает экземпляр объекта на основе прототипа

Методу нужно передать в качестве первого аргумента ссылку на прототип, который будет использован при создании экземпляра

Вторым ( опциональным ) аргументом может быть объект-дескриптор свойств создаваемого экземпляра

☕ 1️⃣
var figure = {
    className: "Figure"
}
var circle = Object.create ( figure )

Если передать null в качестве аргумента, будет создан объект без прототипа:

var emptyObject = Object.create ( null )

☕ 2️⃣

Метод 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__: Object
circle instanceof Figure  // true

☕ 3️⃣

Создадим экземпляр объекта 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 )

Посмотрим результат в консоли:


☕ 4️⃣

Создадим конструктор 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

☕ 5️⃣

Объявим конструктор класса 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 выполняет функцию декоратора


☕ 6️⃣

Объявляем конструктор класса 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 ( "красная" )
redCup
▼ 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 ()

выдаст в консоль сообщение: Посуда вымыта


☕ 7️⃣ __proto__ vs Object.create()

Аналогичный результат можно получить значительно проще, используя свойство __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()


🔗 MDN

© Irina H.Fylyppova 2018
Использование данных материалов или любой их части коммерческими школами ( курсами ) является нарушением авторских прав


Новая версия


1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19

Занятие 1

⤵️

Занятие 2

⤴️ ⤵️

Занятие 3

⤴️ ⤵️

Занятие 4

⤴️ ⤵️

Занятие 5

⤴️ ⤵️

Занятие 6

⤴️ ⤵️

Занятие 7

⤴️ ⤵️

Занятие 8

⤴️ ⤵️

Занятие 9

⤴️ ⤵️

Занятие 10

⤴️ ⤵️

Занятие 11

⤴️ ⤵️

Занятие 12

⤴️ ⤵️

Занятие 13

⤴️ ⤵️

Занятие 14

⤴️ ⤵️

Занятие 15

⤴️ ⤵️

Занятие 16

⤴️ ⤵️

Занятие 17

⤴️ ⤵️

Занятие 18

⤴️ ⤵️

Занятие 19

⤴️ ⤵️

⤴️

ico20 Дополнительно
dir-20 Справочная инфо

Clone this wiki locally