Зачем использовать наследование стиля ООП на основе классов в javascript?

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

По моему опыту, я не нахожу доказательств ни одному из этих мнений. Я думаю, что наследование прототипов javascript просто прекрасно (и я сомневаюсь в полезности навязывания другой парадигмы языку, чем та, на которой он построен). Большинство разработчиков, с которыми я встречался, не так хороши даже в классическом ООП. Итак, каковы причины выбора классического наследования в стиле ООП вместо прототипного наследования?


person Norbert Hartl    schedule 04.05.2009    source источник
comment
На этом спор не заканчивается? Резюмирую интересную статью. Короче говоря, классовое мировоззрение более ущербно, чем мировоззрение прототипов. Итак, мы должны быть осторожны. Вот краткое изложение: carnotaurus.tumblr.com/post/3248631891 /   -  person CarneyCode    schedule 12.02.2011
comment
Вы раскрыли настоящий вопрос, который я задавал :) Только сегодня увидел ваш комментарий. Спасибо за указание на это.   -  person Norbert Hartl    schedule 30.06.2011


Ответы (8)


Я думаю, что ответ в вашем вопросе - большинство программистов гораздо лучше знакомы с ООП на основе классов, чем с прототипами.

На самом деле я бы даже сказал, что большинство не верит, что у вас могут быть объекты без классов.

person Greg    schedule 04.05.2009
comment
Большинство разработчиков, с которыми я сталкивался, не очень хорошо разбираются в прототипах и oop. Так что это было бы просто вопросом, что вы узнаете в первую очередь. И тогда я бы не стал пытаться сделать из него другой язык, как он есть. Я согласен с тем, что большинство людей видят необходимость наличия у классов объектов. Но в javascript он тоже есть. Просто названия разные ;) - person Norbert Hartl; 05.05.2009

обратите внимание, что даже если вы выступаете за ООП на основе прототипов, вы называете его «прототипом», а ООП на основе классов просто «ООП». так вот, вы сами страдаете этим предубеждением, думая ООП=>классы, прототипы=> что-то другое.

и поскольку большинство людей считают, что ООП правильный путь независимо от проблемы, прототипы должны быть хуже.

Итак, чтобы ответить на ваш вопрос, это два фактора:

  1. a bad definition: "OOP => classes"
    • propaganda: "it must be OOP, or you're not worthy"

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

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

    • there are many ways to structure a programming solution, OOP are great at some and lousy at others.
person Javier    schedule 04.05.2009
comment
Я не понимаю, что ты хочешь сказать. Я просто не могу согласиться с твоими предположениями о моих намерениях. - person Norbert Hartl; 05.05.2009
comment
Кстати. Я отредактировал текст, чтобы его было легче неправильно истолковать. - person Norbert Hartl; 05.05.2009
comment
я имею в виду, что наследование на основе прототипов является таким же ООП, как и наследование на основе классов. Называть ООП одним, а не другим подкрепляет идею о том, что прототипов «недостаточно», даже если вы в это не верите, ваш выбор слов работает против вас. - person Javier; 05.05.2009
comment
Что ж, тогда мне нужно потратить еще немного времени, чтобы сформулировать следующий вопрос. Спасибо за указание на это. - person Norbert Hartl; 05.05.2009

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

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

Ни одна парадигма не является более правильной для решения проблемы, чем другая. Я считаю, что главная причина в том, что в наши дни всех учат ООП через Java. Поэтому, когда люди сталкиваются с ООП, они думают «о, классы», потому что это то, с чем они знакомы. И всякий раз, когда они хотят решить проблему, они, скорее всего, будут использовать то, что знают.

Я бы также сказал, что программисту не выгодно использовать парадигму, с которой он не знаком. Большинство из нас должны использовать javascript для веб-разработки на стороне клиента и использовать язык ООП на основе классов на сервере. Я лично не хотел бы этого несоответствия импеданса ООП всякий раз, когда мне приходилось смотреть на javascript-сторону приложения.

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

person Min    schedule 04.05.2009

Долгое время я считал ООП на основе прототипов слабой, плохой и неправильной версией ООП на основе классов. Затем, после того как в мою голову просочилось критическое количество информации, я теперь понимаю ООП более абстрактно, и в целом нахожу оба пути приемлемыми.

person Pavel Feldman    schedule 04.05.2009

Итак, каковы причины выбора классического наследования в стиле ООП вместо прототипного наследования? На самом деле, я считаю, что некоторые фреймворки "как бы" комбинируют подходы. Возьмем, к примеру, паттерн Parasitic Combination Inheritance. Это то, что делает YAHOO.lang.extend.

Он использует прототипное наследование и вспомогательную функцию для наследования прототипов и кражи конструктора. Вау, это звучит сложно... ну да, вот моя реализация и тест, например:

// Prototypal Inheritance
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};
function SubType(name, age) {
    Parent.call(this, name);
    this.age = age;    
};
inheritPrototype(SubType, Parent);  
SubType.prototype.getAge = function() {
    return this.age;
};

У меня есть тест для этого кода:

   describe 'Parisitic Combination Inheritance'
 it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
     sub = new SubType("Nicholas Zakas", 29)
     sub.toString().should.match /.*Nicholas Zakas/
     sub.getAge().should.eql 29
     charlie = new SubType("Charlie Brown", 69)
     charlie.arr.should.eql([1,2,3])
     charlie.arr.push(999)
     charlie.arr.should.eql([1,2,3,999])
     sub.arr.should.eql([1,2,3]) 
     sub.should.be_an_instance_of SubType
     charlie.should.be_an_instance_of SubType
     (sub instanceof SubType).should.eql true 
     (sub instanceof Parent).should.eql true 
 end
    end

И, конечно же, если вы обращаете внимание на мои литералы, вы видите: Николас Закас, парень, от которого я получил это ;) Большие победы для этого: instanceof работает (некоторые говорят, что это большое дело, и я отчасти согласен); экземпляры не разделяют состояние ссылочных типов, таких как массивы (важно!); родительский конструктор вызывается только один раз (важно!).

Кстати, у меня есть примеры большинства популярных шаблонов наследования здесь: Мои примеры TDD JS

person Rob    schedule 29.10.2009

Я бы сказал, что сам язык направляет людей к классическому мышлению, выбирая «новое» в качестве ключевого слова и вводя в спецификацию языка такие понятия, как «конструкторы». В каком-то смысле это ограничивает — представьте себе изменение мышления, если вместо этого у нас будет ключевое слово «клон» и концепция черт а-ля СЕБЯ.

person OdeToCode    schedule 04.05.2009
comment
Неплохо подмечено. Я не уверен, что SELF не пострадает так же, как javascript. Ну в селф надо клонировать но что тебе подсказывает что не будет нового который бы пересобрал клон+сброс значений? И тогда черты будут рассматриваться как форма множественного наследования, известная из C++. Вы не согласны? - person Norbert Hartl; 05.05.2009
comment
История JavaScript печальна: сначала это был вариант Scheme, потом было решено, что я должен быть более «процедурным», поэтому он позаимствовал часть синтаксиса и ключевых слов из C и C++, а непосредственно перед запуском был переименован, чтобы подделать какую-то связь с Java. в конце концов, это самое вводящее в заблуждение программное обеспечение. вы должны действительно понять его, чтобы начать верить, что это не игрушечный язык - person Javier; 05.05.2009
comment
Я знаю, что история javascript печальна. Их подтолкнули к выпуску, чтобы он выглядел как java и даже имел это имя. Весь маркетинг несколько сбил. - person Norbert Hartl; 05.05.2009

Когда я писал свои первые скрипты, было круто и удобно иметь такой простой язык. Но сегодня вы не просто хотите изменить цвет кнопки, вы хотите создавать сложные приложения на JavaScript. Другие могут захотеть использовать ваше популярное приложение и хотели бы, чтобы сообщество предоставляло плагины.

Теперь это намного проще реализовать с помощью ООП, особенно потому, что многие программисты знакомы с концепциями ООП.

person ericteubert    schedule 04.05.2009
comment
Вот именно этого я не понимаю. Конечно, если вы все согласны с тем, что большинство разработчиков знакомы с ООП, я так понимаю. Но что делает ООП более мощным, чем прототипный подход? Ну я сам нахожу супер завышенным. Так что же это еще? - person Norbert Hartl; 05.05.2009

Одной из причин может быть то, что ваша серверная часть, скорее всего, будет объектно-ориентированной (ASP.NET, Java и т. д.), поэтому на клиенте проще мыслить той же парадигмой. Не обязательно лучше, но проще.

person John M Gant    schedule 04.05.2009
comment
Ну нет. Вы сериализуете/упорядочиваете свои данные в каком-то промежуточном формате. Разобраться во что-то другое, ИМХО, не проблема. Даже если у вас есть вещи, которые должны вести себя одинаково на клиенте и сервере, а это бывает редко. - person Norbert Hartl; 05.05.2009
comment
@Norbert: то, что это непрактично, не означает, что это не будет предпринято. См. также: WebForms, GWT... - person Shog9; 05.05.2009