В Javascript функция-конструктор содержит свойство .prototype
, которое содержит любые методы, определенные для этого объекта (либо с прямым присвоением прототипу в ES5, либо с ключевым словом class
в ES6).
Затем, когда вы создаете экземпляр нового объекта с помощью этого конструктора, объект получает указатель на прототип. Когда для этого объекта вызывается метод, интерпретатор Javascript сначала ищет в самом объекте свойство с таким именем и, если не находит там, затем переходит к поиску в цепочке прототипов.
Итак, единственное, что «копируется» во вновь созданный объект в Javascript, — это указатель на прототип. И это работает одинаково в ES5 и ES6. Синтаксис class
в ES6 — это просто новый синтаксис для выполнения того, что мы уже делали вручную в ES5 (назначение методов объекту-прототипу).
На самом деле, вы даже можете получить прототип, если хотите, с помощью Object.getPrototypeOf()
. Важно понимать, что новый объект содержит указатель на объект-прототип (а не копию). Если в объект-прототип вносятся последующие изменения, он становится «живым», и все объекты, созданные до или после, увидят это изменение.
class Car {
constructor(brand, model) {
// initialize instance data
this.brand = brand;
this.model = model;
}
goForward() {
console.log("goForward");
}
goBackward() {
console.log("goBackward");
}
}
let c = new Car("Toyota", "Corolla");
console.log(Object.getPrototypeOf(c)); // shows the two methods goForward, goBackward
console.log(c.brand); // "Toyota"
Теперь, если в классе Car есть методы goForward() или goBackward(), все они будут скопированы в объект myCar.
Новому объекту дается указатель на прототип. Методы не копируются по отдельности.
Насколько я понимаю, это копирование данных и методов является высшим требованием, если мы хотим использовать наследование классов в качестве шаблона проектирования.
Это просто неправда. Наследование не требует копирования всех методов в новый объект. На самом деле существует много разных способов добиться правильного наследования. Javascript использует прототип. C++ использует привязку времени компиляции. Я сам не знаю внутренностей Java, но этот пост относится к таблица методов, на которую каждому объекту в Java дается указатель.
Привносит ли новая структура на основе классов ES6 эту вещь в картину?
ES6 не меняет того, как наследование работает внутри Javascript. ES6 просто вводит синтаксис class
, который представляет собой другой способ объявления конструктора объекта и методов, но приводит к той же внутренней структуре, что и способ, которым мы вручную объявляли методы в прототипе в ES5.
person
jfriend00
schedule
02.09.2017
new Car(...)
в чистом JS. - person Mario F   schedule 03.09.2017myCar.goBackward()
, а в JavaScript это полностью прозрачная конструкция времени выполнения, которая позволяет вам делатьmyCar.goBackward()
. Это никак не влияет на дизайн, просто становится более гибким. - person Bergi   schedule 03.09.2017class
не приносит новую структуру, а только новый синтаксис — концепция работы наследования не изменилась. - person Bergi   schedule 03.09.2017