Sobes.tech
Middle
105
questionbank

Что такое прототипное наследование в JavaScript?

AI答案

sobes.tech AI

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

При доступе к свойству объекта, JavaScript сначала ищет его непосредственно в самом объекте. Если свойство не найдено, поиск продолжается в прототипе этого объекта, затем в прототипе прототипа и так далее, до тех пор, пока свойство не будет найдено или не будет достигнут конец цепочки (null).

Прототипное наследование отличается от классического наследования (как в Java или C++), где объекты создаются из классов, описывающих их структуру и поведение. В JavaScript классы, появившиеся в ES6, являются синтаксическим сахаром поверх прототипного наследования.

Основные аспекты:

  • __proto__: Внутреннее свойство объекта, ссылающееся на его прототип.
  • prototype: Свойство конструктора (функции, используемой как конструктор), ссылающееся на объект, который будет служить прототипом для создаваемых экземпляров.
  • Object.getPrototypeOf(obj): Стандартный способ получить прототип объекта.
  • Object.setPrototypeOf(obj, proto): Стандартный способ установить прототип объекта.

Пример:

// Функция-конструктор
function Animal(name) {
  this.name = name;
}

// Добавляем метод в прототип Animal
Animal.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

// Создаем экземпляр
const dog = new Animal("Buddy");

// Вызываем метод из прототипа
dog.sayHello(); // Вывод: Hello, my name is Buddy

// Прототип dog - это Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // Вывод: true

// Прототип Animal.prototype - это Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // Вывод: true

// Конец цепочки прототипов - null
console.log(Object.getPrototypeOf(Object.prototype) === null); // Вывод: true

Сравнение с классическим наследованием (с использованием классов ES6):

class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Вызов конструктора родительского класса
    this.breed = breed;
  }

  bark() {
    console.log("Woof!");
  }
}

const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Вывод: Hello, my name is Buddy (наследуется от Animal)
buddy.bark(); // Вывод: Woof! (метод Dog)

// Классы в ES6 - сахар над прототипами
console.log(Object.getPrototypeOf(Dog) === Animal); // Вывод: true (наследование классами)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // Вывод: true (наследование методов через прототипы)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // Вывод: true (экземпляр наследует от прототипа класса)

Прототипное наследование — ключевая концепция в JavaScript, понимание которой необходимо для эффективной работы с языком.