JavaRush /Курсы /Модуль 1: Web Core /Знакомство с прототипами

Знакомство с прототипами

Модуль 1: Web Core
20 уровень , 2 лекция
Открыта

3.1 Концепция прототипов

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

Прототип в JavaScript — это объект, от которого другие объекты могут наследовать свойства и методы. Каждый объект в JavaScript имеет скрытую ссылку на другой объект — скрытое свойство [[Prototype]], которое указывает на его прототип.

Этот прототип может иметь свои собственные прототипы, образуя цепочку прототипов (prototype chain). Свойства и методы объекта могут быть унаследованы по этой цепочке. Это позволяет объектам делиться функциональностью и создавать иерархии объектов.

Свойство proto

В JavaScript у каждого объекта есть свойство __proto__, которое указывает на его прототип. Это свойство используется для поиска свойств и методов, если они не найдены в самом объекте.

В этом примере объект child наследует метод greet() от объекта parent:

JavaScript
    
      const parent = {
        greet() {
          console.log('Hello from parent');
        }
      };

      const child = {
        __proto__: parent
      };

      child.greet(); // Выведет: Hello from parent
    
  

3.2 Создание и использование прототипов

1. Object.create()

Метод Object.create() позволяет создать новый объект с указанным прототипом.

Пример:

JavaScript
    
      const parent = {
        greet() {
          console.log('Hello from parent');
        }
      };

      const child = Object.create(parent);
      child.greet(); // Выведет: Hello from parent
    
  

2. Добавление свойств и методов в прототип

Свойства и методы могут быть добавлены в прототип, чтобы они были доступны всем объектам, которые его наследуют.

В этом примере метод speak() добавляется в прототип animal и доступен объекту dog:

JavaScript
    
      const animal = {
        speak() {
          console.log(`${this.name} makes a noise.`);
        }
      };

      const dog = Object.create(animal);
      dog.name = 'Buddy';
      dog.speak(); // Выведет: Buddy makes a noise.
    
  

3. Изменение прототипа объекта

Прототип объекта можно изменить с помощью метода Object.setPrototypeOf().

В этом примере прототип объекта duck изменяется с animal на bird:

JavaScript
    
      const animal = {
        speak() {
          console.log('Animal speaks');
        }
      };

      const bird = {
        fly() {
          console.log('Bird flies');
        }
      };

      const duck = {
        __proto__: animal,
        quack() {
          console.log('Duck quacks');
        }
      };

      Object.setPrototypeOf(duck, bird);
      duck.fly();   // Выведет: Bird flies
      duck.quack(); // Выведет: Duck quacks
    
  

3.3 Работа с прототипами

1. Проверка прототипа объекта

Метод Object.getPrototypeOf() позволяет получить прототип объекта.

Пример:

JavaScript
    
      const parent = {
        greet() {
          console.log('Hello from parent');
        }
      };

      const child = Object.create(parent);

      console.log(Object.getPrototypeOf(child) === parent); // Выведет: true
    
  

2. Проверка принадлежности объекта к прототипу

Оператор instanceof используется для проверки, является ли объект экземпляром определенного конструктора или прототипа.

Пример:

JavaScript
    
      function Person(name) {
        this.name = name;
      }

      const john = new Person('John');

      console.log(john instanceof Person); // Выведет: true
    
  

3. Перебор свойств объекта и его прототипа

Для перебора свойств объекта и его прототипа можно использовать цикл for...in, который перечисляет все перечисляемые свойства.

Пример:

JavaScript
    
      const parent = {
        greet() {
          console.log('Hello from parent');
        }
      };

      const child = Object.create(parent);
      child.name = 'Child';

      for (let key in child) {
        console.log(key);
      }

      // Выведет:
      // name
      // greet
    
  

Для перебора только собственных свойств объекта используется метод Object.keys() или цикл for...of с методом Object.entries().

Пример:

JavaScript
    
      const parent = {
        greet() {
          console.log('Hello from parent');
        }
      };

      const child = Object.create(parent);
      child.name = 'Child';

      console.log(Object.keys(child)); // Выведет: ['name']

      for (const [key, value] of Object.entries(child)) {
        console.log(key, value);
      }

      // Выведет:
      // name Child
    
  
1
Задача
Модуль 1: Web Core, 20 уровень, 2 лекция
Недоступна
Методы в прототипе
Методы в прототипе
1
Задача
Модуль 1: Web Core, 20 уровень, 2 лекция
Недоступна
Цепочка прототипов
Цепочка прототипов
Комментарии (5)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Maxim Kulikov Уровень 48
8 июля 2025
Во второй задачи в условиях ни слова не сказано, что создаваемые методы должны что-то делать, но задача не принимается, потому что нужно было в хрустальном шаре между строк прочитать, что там вывод в консоль требуется, который запарывает проверку... Как же все в курсе на отъебись сделано.
Vadim Makarenko Уровень 42
22 августа 2025
Объективности ради нужно сказать, что суть методов видна по комментариям к шаблону задачи на основном экране. Хотя они могли появиться уже после этого замечания. Конечно, лучше бы этим надписям быть в самом задании.
RayCowperwood Уровень 48
4 июня 2025

__proto__
устарел и его использование не рекомендуется. Это свойство в JavaScript позволяет получить или изменить прототип объекта, но оно было признано медленным и потенциально небезопасным. Вместо него рекомендуется использовать

Object.getPrototypeOf()
и

Object.setPrototypeOf()
Лучше использовать

Object.create()
Это более современный и оптимизированный способ работы с прототипами.
RayCowperwood Уровень 48
4 июня 2025
а вообще - extends применяется в классах ES6 и позволяет создать подкласс, который наследует свойства и методы родительского класса. Это более современный и удобный способ наследования.

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} издает звук.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} лает.`);
  }
}

const dog = new Dog("Барсик");
dog.speak(); // "Барсик лает."
- prototype используется в более старом стиле объектно-ориентированного программирования в JavaScript. Он позволяет добавлять методы и свойства к объектам и их конструкторам. Основное отличие в том, что extends делает код более читаемым и удобным, а prototype используется в старых версиях JavaScript и при работе с функциями-конструкторами
Vadim Makarenko Уровень 42
22 августа 2025
Для себя я понял, что свойство __proto__ относится к объектам, а свойство prototype - к классам и функциям-конструкторам. Сейчас действительно удобнее работать с объектами и классами с помощью новых ключевых слов типа class, extends, costructor, super, но знать о прототипах нужно, т.к. JavaScript - прототипно-ориентированный язык, где классы, в отличие от Java, C++, - лишь синтаксический сахар. Кроме того, бывает, что на собеседованиях просят модернизировать базовые классы JavaScript, чтобы добавить им специфические возможности. Например создать для Array метод вывода элементов в консоль в заданном формате. Вот тут как раз prototype и пригодится. Хотя в реальном коде так делать не рекомендуется, чтобы не "захламлять" оригинальные классы.