Sobes.tech
Junior
109
questionbank

Объясните, как работает наследование в JavaScript.

AI答案

sobes.tech AI

Наследование в JavaScript основано на прототипах. Каждый объект имеет внутреннее свойство [[Prototype]] (доступное через __proto__ или Object.getPrototypeOf()), которое указывает на другой объект.

При попытке обратиться к свойству или методу объекта, если оно не найдено непосредственно в объекте, JavaScript ищет его в [[Prototype]] этого объекта, затем в [[Prototype]] прототипа и так далее по цепочке прототипов, пока не достигнет конца (объекта Object.prototype), у которого [[Prototype]] равен null.

Это и есть прототипное наследование.

Классы в ECMAScript 2015 (ES6) являются синтаксическим сахаром над прототипным наследованием. Они предоставляют более привычный синтаксис для работы с прототипами и создания иерархий объектов.

Пример использования прототипного наследования до ES6:

// Конструктор родителя
function Animal(name) {
  this.name = name;
}

// Метод родителя на прототипе
Animal.prototype.sayHi = function() {
  console.log(`Привет, я ${this.name}`);
};

// Конструктор потомка
function Dog(name, breed) {
  // Вызываем конструктор родителя
  Animal.call(this, name);
  this.breed = breed;
}

// Устанавливаем прототип потомка на прототип родителя
// Сохраняем ссылку на конструктор Dog
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// Добавляем метод потомка
Dog.prototype.bark = function() {
  console.log("Гав-гав!");
};

// Создаем экземпляр потомка
const myDog = new Dog("Бобик", "Лабрадор");

// Используем методы родителя и потомка
myDog.sayHi(); // Выведет: Привет, я Бобик
myDog.bark();  // Выведет: Гав-гав!

Пример использования классов (ES6):

// Родительский класс
class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Привет, я ${this.name}`);
  }
}

// Дочерний класс, наследующий от Animal
class Dog extends Animal {
  constructor(name, breed) {
    // Вызываем конструктор родителя
    super(name);
    this.breed = breed;
  }

  bark() {
    console.log("Гав-гав!");
  }
}

// Создаем экземпляр дочернего класса
const myDog = new Dog("Рекс", "Немецкая овчарка");

// Используем методы родителя и потомка
myDog.sayHi(); // Выведет: Привет, я Рекс
myDog.bark();  // Выведет: Гав-гав!

Ключевые моменты наследования в JavaScript:

  • Прототипы: Каждый объект имеет прототип.
  • Цепочка прототипов: При поиске свойства или метода обходятся прототипы вверх по цепочке.
  • [[Prototype]]: Внутреннее свойство, указывающее на прототип.
  • __proto__: Устаревший, но часто используемый способ доступа к [[Prototype]].
  • Object.getPrototypeOf(): Рекомендуемый способ доступа к [[Prototype]].
  • Конструкторы и prototype: До ES6 использовались для создания объектов и установки их прототипов.
  • Классы (ES6): Синтаксический сахар для прототипного наследования, использующий ключевые слова class, extends, super.