Каковы шаблоны, которые вы могли бы использовать с наследованием прототипов, которые вы не можете с классом?

Кажется, что все согласны с тем, что наследование прототипов проще и гибче, чем наследование классов. То, что я не видел в литературе, которую я прочитал, - это очень много примеров того, что вы можете сделать с наследованием прототипов, которое вы не можете с классическим. Поэтому я задаю простой вопрос:

Каковы некоторые шаблоны, которые вы можете использовать с наследованием прототипов, которые вы не можете с наследованием классов, и каково руководство, которое вы бы дали до того, когда/если его использовать?

Ответы

Ответ 1

Одно отличие (возможно, по крайней мере, концептуально) состоит в том, что наследование класса подразумевает, что дочерний тип IS-A родителя. Наследование прототипа не подразумевает такой импликации; млекопитающее является прототипом для кошки (определение Merriam-Webster говорит, что это означает "шаблон для" ), но больше ничего. Кошка бесплатно удаляет/добавляет/изменяет поведение по своему усмотрению.

Ответ 2

Хорошо, я добавлю один, используйте тот факт, что ссылки прототипа являются живыми для методов обезьян-патчей для всего класса объектов:

var Cat = function(catName) {
    this.catName = catName;
};
Cat.prototype.meow = function() {
    console.log(this.catName+" says meow");
}
var mittens = new Cat("Mittens");
var whiskers = new Cat("Whiskers");
mittens.meow(); // "Mittens says meow"
whiskers.meow(); // "Whiskers says meow"

// All cats are now angry
Cat.prototype.meow = function() {
    console.log(this.catName+" says hissssss");
}
mittens.meow(); // "Mittens says hissssss"
whiskers.meow(); // "Whiskers says hissssss"

Это было бы полезно, если бы у вас были объекты, которые внезапно должны начать действовать совершенно другим, но последовательным образом в ответ на какое-то глобальное событие. Может быть, для чего-то вроде:

  • Темы и скинирование
  • Работает ли страница в режиме "онлайн" или "автономном режиме" (в то время как онлайн все запросы сохраняются/извлекаются через ajax, а автономные запросы перенаправляются в хранилище браузера).

Ответ 3

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

Итак, я рассмотрю ваш вопрос так, как если бы вы имели в виду:

Каковы некоторые шаблоны, которые вы можете использовать с наследованием прототипа JavaScript, которые вы не можете сделать с наследованием класса на поддерживающих его языках?

R = В общем, большинство объектно-ориентированных языков, основанных на классе Inheritance, создают объекты с жесткой структурой, они всегда будут иметь одинаковые методы и свойства в течение своей жизни, и все объекты тех же классов будут иметь одинаковые структура.

Итак, в общем, шаблоны, которые вы можете применять с языком на основе прототипа, который не может быть реализован с помощью языка наследования класса, зависят от:

  • Добавление или удаление методов или свойств объектов, на лету

* Это так хорошо поддерживается в JavaScript из-за его динамического взаимодействия между доменами. Иногда вам приходится загружать внешние скрипты с других веб-сайтов, но вам нужно добавить новые функции, не имея возможности изменить исходный код из этих внешних библиотек.

Ответ 4

Я не думаю, что согласен с вашей предпосылкой, но основным преимуществом наследования на основе прототипов является то, что он позволяет назначать свойства и методы во время выполнения всем членам класса, даже если уже есть экземпляры этого класса.

Теоретик во мне на самом деле съеживается на некоторые из этих последствий. Представьте, что вы отлаживаете что-то, где вы не представляете, какой фрагмент кода полностью переопределил вашу структуру классов. Это не сложно.

Но я скажу, что это оказалось полезным:

Однажды, когда я работал в ActionScript 2 (не для слабонервных, так как это почти недетерминированный язык) внутри контейнера ActionScript 3. Неизвестный побочный эффект этой проблемы заключается в том, что она устраняет идею уровней памяти (что-то существенное для кода моей компании). Я смог добавить строку: MovieClip.prototype._level0 = _root;, и она решила проблему.

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