Pull to refresh
2
0
Dmitry Soshnikov @dsCode

User

Send message
Вот еще кодом можно показать:

Код из ES4:

dynamic class A {
  function test() {}
}

var a = new A();
var b = new B();

a.test();
b.test();

a.test === b.test // false

a.hasOwnProperty('test'); // true
b.hasOwnProperty('test'); // true

// наследование - как в Java

class B extends A {} // и т.д.


На этом этапе все полностью то же самое, можно сделать в ES3 посредством функции-конструктора:

function A() {
  this.test = function () {};
}

// дальше тоже самое


А теперь с хранением свойства «test» в прототипе конструктора:

function A() {}

A.prototype.test = function() {};

var a = new A();
var b = new A();

print a.test === b.test; // true

// наследование

function B() {
this.b = 20;
B.superсlass.call(this, arguments);
}

var __inheritance = function() {};
__inheritance.prototype = A.prototype;
B.prototype = new __inheritance();
B.prototype.constructor = B;
B.superсlass = A; // явная ссылка на «А» для вызова родительских методов
> и насчет холиваров class vs. prototype

а, кстати, — в этом топике холивора не было ))

И я предлагаю, когда кто-то захочет сказать «нах классы», говорить: «я вот только знаю статические классы и чуть-чуть слышал о прототипах в JS. Но я хочу заявить — не надо извращаться над JS, примите его таким, какой он есть (да, и… если честно, — это не моя фраза, я ее слышал у одного профи)». Вот тогда будет честно и справедливо! (никого не обижаю — в шутку это все говорю)

> чем же так хорош prototype-подход, какие он дает конкретные преимущества

Основное преимущество — это расшаривание свойств между всеми порожденными объектами. Таким образом, потребляется меньше памяти. Обращение к этим расшаренным свойствам (чаще всего — это методы) происходит посредством делегирования к прототипу конструктора (именно там они хранятся). Главная суть — если свойство не найден в самом объекте, его поиск продолжается в цепи прототипов. Эта цепь и образует наследование.
Привет, Zeroglif! ;)

Я вот когда говорил об эффекте «взрыва» и его «взрывной волне» как раз имел в виду высказывания вроде твоего. Несомненно, это правда, — особенно, касаемо тяжелых оберток или, когда имитируют функции, которые и так в JS есть (например, тема про имитацию функций из PHP). Но это может иметь и побочный эффект — тех же «чучел», — когда могут насмотреться на высказывание профи и потом неосознанно везде писать то же самое (при этом, как я часто замечаю, уровень знаний в JS несколько ниже, чем подается во фразе, услышанной у профи).

> Скоро и железо отстанет. ;)

Э-э, нет ;) Остановятся, если увидят, что «железо» еще не может развиться до определенной стадии (ну, не совсем уж дураки «там сидят»). Касаемо самого JS, — снова абстрактно — любая идеологическая конструкция в нем (хоть замыкания, хоть анонимные функции, хоть динамические объекты, хоть и т.д.) — есть (если очень абстрактно) также синтаксически удобный «сахар» (по отношению к языкам, которые не имеют таких возможностей и вынуждены писать кода в несколько раз больше). При этом, эти удобные обертки в любом случае понесли потери в ресурсах — статические классы быстрее динамических.
Для разъяснения подобных вопросов лучше сразу смотреть в спецификацию.
> JavaScript не объектно-ориентированный

Откройте стандарт, пункт 4 (самое начало), второй абзац:

ECMAScript is an object-oriented programming language

> И ООП (статическое), как раз является не оберткой, а эмуляцией.

Да нет здесь никакой эмуляции. Нет здесь никакой статики (и быть не может!). Обычная wrapper-функция-конструктор, которая делает удобным подмену прототипа на нужный.

> классы в более классическом их понимании

Все же, мне кажется, стоит говорить, «статические» классы. Потому что, опять, в Питоне и Руби — тоже классы, они также классические, но при этом — полностью динамические.

> Кому-то это кажется синтаксическими сладостями

Они не должны казаться таковыми. Они являются таковыми в единственно верном понимании (да простят меня все за такую формулировку и не сочтут за навязывание мысли).

> а кто-то именно за это цепляется и видит JS в свете «более ООП»

Так вот расскажите им (каждый раз, когда будете встречать), что это только лишь обертка, и что смотреть нужно (если они хотят понять JS) именно так, и что JS — изначально — ООП-язык и насквозь пронизан наследованием (как пример, можно попросить объяснить, что значит 1.toString();).

> предпочитаю использовать ?:

дело привычки
typo:
«не больше! ни меньше!» => ни… ни, конечно (тороплюсь просто)
> а с точки зрения практического использования, я сильно сомневаюсь. Просто честно, не вижу смысла эмулировать какие-то вещи из других языков просто чтобы синтаксический сахар получить…

Хорошо, еще раз — давайте напишем тройной уровень наследования (и снова, забегая вперед, скажу, что там будет один повторяющийся кусок кода, и мы его вынесем в функцию и назовем ее Inheritance) и посмотрим, как этот код можно оптимизировать с точки зрения reusing'а.
> Ну как она работает, я более менее знаю, уже не первый год с ним общаюсь

ну, тогда и динамическую классовую модель в Руби и Питоном сразу поймете ;)
Да и… Рассуждая о понятии класс, я не призываю к оберткам, я как раз отметил, что все это вы можете делать и без оберток. Я лишь хочу, чтобы люди (и те, которые пишут новые обертки, и те, которые не ленятся каждый раз писать «извращенцы») услышали слово «альтернативный» (ООП-подход) и не несли в общество безграмотность, выставляя классовый подход «пуголом» или же не понимая прототипного подхода.
> Все дело в том, что статическая классовая парадигма для многих разработчиков (далеко не всех!) является стандартом при разработке сложных приложений.

Вы это Руби- и Питон- программерам скажите (я имею в виду слово статическая)
> Я потенциально не доверяю фреймворкам

да при чем здесь какие-то фреймворки? :) И вообще, что есть фреймворк? У меня, например, был свой фреймворк еще до того, как появились Prototype.js и jQuery. Я просто вынес удобные функции в одно место и юзал их.

Забудьте пока про слово «статика», просто посмотрите сходство (везде одна динамика, разная терминология, слегка отличающаяся идеология, в целом — 80%-сходство):

habrahabr.ru/blogs/javascript/40909/#comment_996830
habrahabr.ru/blogs/javascript/40909/#comment_997247
> JavaScript версии до 2.0 не является ООП по простой причине.

Является. Конечно, является. Это ООП-язык с алтернативной (не дождетесь — я не устану повторять это слово и выделять его курсивом ;)) парадигмой.

ru.wikipedia.org/wiki/Прототипное_программирование

> Далее, в версии 2.0 вводятся ключевые слова, которые позволят осуществлять ООП, но сейчас этого нет, потому не стоит искать то, чего нет.

Да я и не ищу, я знаю, что оно есть. Я, в принципе, вообще не играю сейчас с Вами в игру «Кто интересней интуитивно догадается, что есть, а что нет в JS», я лишь рассуждаю относительно спецификации ECMAScript (абстрактно раздвигая ее рамки, проводя параллели с другими динамическими ООП-языками — Python и Ruby, где фигурирует понятие class).

По поводу 2.0. Давайте, тоже напишем небольшой пример, и посмотрим, что мы имеем в 2.0. (ES4) и 1.5 (1.6 / 1.7 / 1.8) (ES3). И как мы вынесем один повторяющийся кусок кода в функцию Inheritance.

> Ниже верно сказано «примите его таким, какой он есть».

Да я не сомневаюсь, что верно =) Я принял его таким, какой он есть, и вижу его на «буквах» (на «формулах»), а не на «числах».
> я не знаю как это назвать…

Вот и я о том же. А дальше я попрошу взглянуть в сторону Ruby и Python'a — и найти 80%-сходство (при том, что названо это class).

> это два противоречащих друг другу принципа

противоречат только статика-динамика. Руби и Питон — динамические языки (с понятием class, очень схожим с ООП-моделью JS)

> Как эксперимент — зачет, но в проектах такое применять не следует…

да что жы Вы все эту шарманку крутите? ;) Хорошо. Давайте продемонстрируем тройной уровень наследования (я, заранее забегая, скажу — что там будет повторяющийся кусок кода, мы его вынесем (следуя code reuse) в функцию и назовем ее Inheritance).
> язык следует использовать так, как он создан, не надо языку с динамической типизацией и прототипами притягивать за уши парадигмы и приемы других языков.

Вероятно (наиболее), что если человек говорит так, то он сам может не понимать, как работает OOP-модель в JS. Я не знаю, насколько это относится к Вам, буду верить, что в меньшей мере. Внутри обертки — используется именно это. Это лишь синтаксический сахар (не больше, ни меньше! вот — не больше! ни меньше!) для удобного описания наследования.

Скажите, как бы изменилось Ваше отношение к этому сахару, если бы главная оберточная функция была названа не Class, а, например, Inheritance? Или moyaUdobnayaObertkaDlyaPrototypnogoNasledovaniya?

Другой вопрос, что новичкам надо объяснять и показывать на примерах, что есть альтернативная ООП-модель и именно она используется в JS. И обязательно отметить, что смотреть на это все нужно только как на обертку — без изменения прототипной парадигмы.
> Зачем из прототипного языка делать непонятно что…

Да тренируются люди, расслабьтесь Вы :) пишут просто удобные обертки — нет в этом ничего плохого, если они понимают суть вещей. Другой вопрос к Вам — что такое «непонятно что»?

> Инструмент должен работать так, как задумано.

Да он и работает так, как задумано (по-другому просто нельзя в данном случае реализовать)

> К тому же мне кажется, что всякие такие обертки не будут ускорять работу скриптов ;).

Производительность снижается за счет применения синтаксического сахара (часто — удобного).

> Имитируется только синтаксис определения классов как в статической парадигме.

да не только как в статической, Руби с Питоном — динамические

Одна из основных идей статической модели — увеличение производительности за счет того, что не нужно каждый раз анализировать объект при обращении к его пропертям. Вместе с тем, статическая модель менее гибкая в организации. Поэтому, повторю — обе модели имеют свои плюсы и минусы. Не стоит смотреть на эти обертки, как на механизм, позволяющий «довести до ума» :) ООП-модель в JS. Смотрите на эту обертку — просто как на обертку. И всем передайте, что смотреть нужно именно так, тогда понимание различных парадигм (на «буквах», на «формулах», а не на «конкретных числах») придет очень быстро.
typo:
эфектом -> *эффектом
Ну тоже одну и ту же пластику не надо заводить постоянно. Ведь любая подобная тема содержит подобный Вашему комментарий. Причем, я склонен полагать, он появляется эфектом «взрывной волны», где «взрывом» являлось высказывание профи (при этом профи видет, как устроен JS и как устроенны другие языки, например Python и Ruby).

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

А теперь вопрос лично к Вам — что Вы подразумеваете под «извращением» в данном случае?
Ну и опять повторю — схожая идеологически модель, используется в Python и Ruby (только там это названо class) — вы не найдете и там статики, которую хотите сымитировать — объекты, классы (которые тоже объекты), их проперти, методы и т.д. — можно менять динамически в рантайме — так же как и в JS. Но — это уже названо class (сходство, естественно, не полное — процентов 80, но идеологически — в одну сторону смотрят). С таким подходом — можно идти в Python и Ruby и менять их организацию — вот только что-то останавливает — там, вроде как, уже есть слово class, да? :)

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity