Прототипы в JavaScript

Содержание

Прототипы в JavaScript - это механизм позволяющий наследовать объектам, свойства других объектов.

Сразу же начнем с примера и создадим два объекта student и programs, где в первом будет лежать информация о студенте, а во втором программы для изучения JavaScript согласно уровня ученика.

    
    let student = {
      name: 'Дмитрий',
      age: 28,
      level: 'junior',
    }
    
    let programs = {
      junior: 'Основы JavaScript',
      middle: 'Продвинутый уровень',
      senior: 'Продвинутая архитектура проекта',
    }
    
    Object.setPrototypeOf(student, programs)
    console.log(student.junior) // Основы JavaScript
    

С помощью метода Object.setPrototypeOf() устанавили прототип объекта programs для student. Другими словами сделали доступным объекту student все свойства и методы, которые есть в programs. Проверить это можно обратившись через объект student к свойству junior - результатом будет значение Основы JavaScript.

Задать прототип, можно также с помощью свойства __proto__ , которое до сих пор поддерживается браузерами, но считается устаревшим.

    
    student.__proto__ = programs
    

[[Prototype]]

Прототип - это объект, который хранится в [[Prototype]] и содержит в себе различные свойства и методы.

  
  let testObject = {}
  console.log(testObject)
  

Если создать пустой объект и посмотреть в console, то можно увидеть свойство [[Prototype]] и то, что оно ссылается на объект, который содержит в себе другие свойства. Также если здесь прописать наш объект и поставить после него точку, браузер предложит доступные методы, как раз из прототипа.

прототип

Прототипы и функция конструктор

Для понимания работы функции конструктора посмотрим на работу встроенного объекта Date.
  
  let date = new Date()
  console.dir(date)
  
date object

Date доступен из коробки и предоставляет методы для работы с датой и временем. Для того, чтобы получить доступ до этих методов, нам нужно всего лишь создать свой экземпляр объекта используя оператор new.

В JavaScript можно самостоятельно писать похожие объекты и использовать их для создания отдельных экземпляров.

Создадим функцию конструктор Student и экземпляр объекта, который запишем в переменную student1.

  
  function Student(name, age, level) {
    this.name = name
    this.age = age
    this.level = level
    this.message = `Студент ${this.name}, в возрасте ${this.age} лет пришел на курсы JavaScript c уровнем знания ${this.level}`
  }
  
  
  let student1 = new Student('Дмитрий', 28, 'junior')
  console.log(student1.message) // Студент Дмитрий, в возрасте 28 лет пришел на курсы JavaScript c уровнем знания junior'
  

Теперь для того, чтобы создавать однотипные объекты в которых будет хранится информация о студентах и будут доступны общие методы, нам не нужно прописывать все с нуля, а достаточно создать экземпляр объекта Student, в прототипе которого и будет записана вся нужная нам информация.

Цепочки прототипов

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

Возьмем для примера все тот же объект Date.

  
  let date = new Date()
  console.dir(date)
  
date object

И в console видим, что для date доступны, как методы связанные с датой, так и стандартные, к каким относится toString(). Развернув [[Prototype]] мы сможем увидеть вложенность прототипов.

Свойства в свою очередь ищутся сверху вниз и если интерпретатор находит нужное, тогда поиск останавливается.

  
  let programAcademy = {
    course: 'JavaScript'
  }
  
  let programAcademy2 = {
    course: 'React'
  }
  
  Object.setPrototypeOf(programAcademy, programAcademy2)
  console.log(programAcademy.course) // JavaScript
  

Свойство course из прототипа programAcademy2 игнорируется.

Итого

1. Под прототипом могут понимать, как метод позволяющий наследовать объектам свойства друг друга, так и непосредственно объект с наследуемыми свойствами.

2. Все объекты в JavaScript имеют свойство [[Prototype]], которое ссылается на объект, называемым прототипом.

3. Свойства __proto__ считается устаревшим, а для получения и установки прототипов рекомендуется использовать методы getPrototypeOf() и setPrototypeOf().

4. Методы и свойства сначала считываются из самого объекта, если там ничего не найдено поиски продолжаются в прототипе.

5. Прототипы это тема, которая необходима для понимания основ объектно ориентированного программирования.