Имеет ли использование прототипов в JavaScript какие-либо реальные преимущества? - PullRequest
2 голосов
/ 29 августа 2010

Я только что закончил работу Дуга Крокфорда The Good Parts , и он предлагает три различных способа наследования: эмуляция классической модели, наследование на основе прототипов и функциональное наследование.

В последнем он создает функцию, своего рода фабрику, которая выплевывает объекты, дополненные желаемыми методами, которые строятся на других объектах;что-то вроде:

var dog = function(params) {
    // animal is the 'super class' created
    // the same way as the dog, and defines some
    // common methods
    var that = animal(params);
    that.sound = 'bark';
    that.name = function () {};
    return that;
}

Поскольку все объекты, созданные таким образом, будут иметь ссылку на одни и те же функции, объем памяти будет намного ниже, чем при использовании, например, оператора new.Вопрос в том, даст ли прототипный подход какие-либо преимущества в этом случае?Другими словами, являются ли объектные прототипы как-то «ближе к металлу», которые обеспечивают преимущества в производительности, или это просто механизм удобства?

РЕДАКТИРОВАТЬ: я упросту вопрос.Прототипы против их эмуляции через композицию объектов.До тех пор, пока вам не требуется, чтобы все экземпляры объектов обновлялись с помощью новых методов, что удобно только для прототипов, есть ли какие-либо преимущества в использовании прототипов?

Я написал Дугу Крокфорду по электронной почте, и он сказал следующее:

[Использование приведенного выше функционального подхода и прототипов] не так уж много памяти.Если у вас есть огромное количество объектов, умноженное на огромное количество методов, вы можете попробовать прототип.Но памяти в наши дни много, и только экстремальные приложения заметят это.

Прототипы могут использовать меньше памяти, но могут иметь немного более медленный поиск, особенно если цепочки очень длинные.Но, как правило, это не заметно.

Ответы [ 3 ]

1 голос
/ 29 августа 2010

Есть много мнений по этому поводу, и мнение Крокфорда не обязательно правильное.

Основным недостатком модификации прототипов является то, что это может усложнить работу с другими библиотеками javascript.

Но недостаток функционального способа создания классов Крокфордом заключается в том, что вы не можете так просто добавить метод или поле ко всем экземплярам типа.

См. Закрытие: Полное руководство для некоторых критических комментариев к мнению Крокфорда о классах и наследовании в javascript: http://my.safaribooksonline.com/9781449381882/I_sect1_d1e29990#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE0NDkzODE4ODIvNTE0

Такие библиотеки, как Dojo, Google Closure Library (которая, похоже, копирует стиль Dojo) и, возможно, YUI, имеют свою собственную систему классов, которая, кажется, является хорошим промежуточным положением. Мне нравится система Dojo, вероятно, лучшая, потому что она поддерживает Mixins, в отличие от Closure. Некоторые другие системы классов, не привязанные к инструментарию GUI, включают в себя Joose, JS.Class и JavascriptMVC (проверьте последнюю, особенно если используется jquery).

1 голос
/ 29 августа 2010

Экземпляры не все ссылаются на одни и те же функции и т. Д. Каждый вызов "dog" создает новый экземпляр функции "name".

0 голосов

Однажды я создал графический интерфейс, поддерживаемый классом, который не имел большой поддержки на основе событий для необходимой информации.В графическом интерфейсе реализован универсальный интерфейс, в котором передается экземпляр этого класса, поэтому я не могу наследовать от этого класса, поэтому я сделал нечто похожее на наследование на основе прототипов, я создал прокси-объект, который оборачивает экземплярэтого класса, когда он передается в мой графический интерфейс.Прокси перехватывает интересующие нас методы, которые изменяют состояние, и сообщает о них как о событиях.Затем весь GUI вращался вокруг использования этих событий.

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

Просто не было другой жизнеспособной альтернативы.Единственными альтернативами были:

  1. Создать объект, который составляет объект, переданный в GUI (как я уже упоминал выше).Этот объект затем будет воспроизводить каждую функцию в исходном классе для реализации того же интерфейса и добавлять события, так что он фактически такой же, как способ прокси-объекта.
  2. Имейте мутацию состояния отслеживания GUI в переданном объекте,Это было бы боль и ошибка.
...