Pull to refresh

Comments 30

Спасибо за ежемесячную статью о прототипах в JavaScript!!1
Да ладно, от кода из этой статьи волосы на подмышках дыбом встают. Ни одного упоминания даже о Object.create, а obj.__proto__=blahblahblah хватает, конструкторы на return this заканчиваются…
Спасибо за критику :)

Я решил не использовать в объяснении механики прототипов то, чего нельзя использовать в IE6. Даже __proto__ использовал только вскользь.

Впрочем, я ожидал, что критика коснётся в основном того, что используется printf() в C++, или какой-нибудь подобной ерунды. Хорошо, что она началась с действительно фундаментальных недостатков статьи, таких как Object.create.
Я решил не использовать в объяснении механики прототипов
var fooProto = { "foo": "prototype!" };
var f = function() { };
f.prototype = fooProto;

А теперь злой фокус, который может ожидать новичков после прочтения вашей статьи:

var object = new f;

object.constructor.prototype.bar = 'FUCK!'; 
console.log(object.foo, 'Object.prototype'.bar); // prototype!, FUCK!
Если бы это был фокус, который действительно ждёт новичков после прочтения моей статьи, то это было бы здорово.

Первая проблема, которая действительно появляется у новичков — это почему нужно писать Person.prototype.foo вместо Person.foo. Не переоценивайте новичков.
Даже __proto__ использовал только вскользь.

Его лучше вообще не использовать, эта фишка не стандартизирована, сегодня есть — завтра нет: mdn
Использовать его можно, но «с головой».
В ES6 должны его включить: B.3.1.1 Object.prototype.__proto__
Да ладно

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

Ни слова о полиморфизме, наследовании ES5, и пр.

На вскидку автору:

var foo = function() {
   this.hellow = 'Hellow ';
};

var bar = function() {
   foo.apply(this);
   this.world = 'World!'
};

var object = new bar;

alert(object.hellow + object.world) // 'Hellow World!'
Чтобы раскрыть тему до уровня, произвольно назначенного комментатором хабрахабра, надо написать книгу. Такой задачи не стояло. Стояла задача показать механизм прототипов и позволить сформироваться соответствующей интуиции. Дело в том, что это учебный материал, а не справочный. Если учебный материал сделать чрезвычайно точным и полным описанием реальности, студенты отваливаются и материал перестаёт справляться со своей задачей. Приходится искать баланс.

Что касается .apply и .call — это немного другая тема, отличная от темы прототипов в JS. Это тема функциональных контекстов в JS, и достойна другой статьи, которая показывает на примерах механику этого процесса. Если сделать такую статью качественной и полной, она будет едва ли не в половину от данной. Теперь представим, что нам нужно объяснить одновременно и .apply/.call, и прототипы. Стоит ли нам соединять эти две длинные статьи вместе, в одну большую портянку, говорящую обо всём? Я считаю, что не стоит. Те, кто считает, что стоит, пишут книги по 1000+ страниц, разжёвывающие каждую тему.

Короче, кроме корректности и полноты у текста есть характеристика «может ли он научить». Сделать одновременно корректный, полный и обучающий текст, да так, чтобы не расплескать по дороге учеников — это адская задача.
UFO just landed and posted this here
Было бы куда интереснее рассмотреть тему приватных полей и использования трюков с замыканиями и call.
Напишу, а первый комментарий будет «Опять эти ежемесячные введения в замыкания от хаскелистов» :)

А если серьёзно, то что именно стоит рассмотреть? call/apply? Ведь есть на хабре такие статьи, какой именно подачи не хватает?
С JavaScript никогда дела не имел, поэтому с интересом статью прочитал. Написано неплохо для обзорного понимания, спасибо.
UFO just landed and posted this here
У меня в коде единственной «ошибкой» можно считать отсутствие инициализации объекта. То есть, использование malloc() вместо calloc(), что порождает объект, инициализированный мусором. Это было сделано сознательно, в иллюстративных целях. Потому что если C++ и Java программисты ещё помнят про malloc() в C, то про calloc() помнят уже меньше.

Если мысленно заменить «malloc(» на «calloc(1,», код мгновенно становится рабочим и корректным. Но у студентов по мере прочтения появляются вопросы к периферийной, неосновной части текста, что затрудняет обучение JavaScript'у.

Что касается непрозрачных объектов в C — да, подобное скрытие является стандартной практикой.
UFO just landed and posted this here
Меня вот что удивляет: почему классы до сих пор не внесены в стандарт ECMAScript? Видно же, что каждый JS-программист, создающий что-то сложнее HelloWorld'а, просто вынужден написать собственную реализацию классов через прототипы (потому что без классов как без рук, а чисто прототипный код быстро превращается в лапшу, полностью теряя структурность уже на 50000 строчек).
Но нет, они упорно твердят, что классы «нинужны», ибо есть ведь миллион кривых реализаций через прототипы.
Просто классоненавистничество какое-то…
Ввели бы в стандарт классы и возможность явной типизации, и сколько сил сэкономили бы разработчикам!
просто вынужден написать собственную реализацию классов через прототипы (потому что без классов как без рук, а чисто прототипный код быстро превращается в лапшу, полностью теряя структурность уже на 50000 строчек).

Вы не правы. Прототипы в JS плохи не потому что «не как классы в Java», а потому что многословны. Многословано делать наследование и добавлять методы, потому приходится это оборачивать в функцию. Необходим только лёгкий сахар для того, чтобы есть.
Ну, не только. Там совершенно не хватает элементарных базовых вещей. Инкапсуляции — нет, интерфейсов — нет, перегрузок — в нормальном виде тоже нет. Можно продолжать еще долго.
Инкапсуляция — это не модификатор «private», это сокрытие реализации под интерфейсом.
Перегрузки в таком виде, как в Java и не нужны, как и интерфейсы
Ну, я про прайват и не говорил, если что (хотя и его тоже нет). А инкапсуляция в общепринятом смысле это вот. И как ее надежно реализовать без сокрытия данных я лично плохо представляю.
Мне, например еще много чего там не хватает: отсутствие контрактов, условная компиляция — те же ассерты (я в курсе как работает JS, но все равно не хватает :)) и еще куча всего. Обиднее всего то, что язык дает другие очень мощные возможности, связанные с динамической типизацией и прочими динамическими фокусами, но использовать эти возможности где-то, кроме библиотек, никто в здравом уме не станет.
Javascript целенаправленно не учил, по-этому с интересом прочитал статью. Спасибо!
… В общем, мы «захламляем» пространство имён, делая с течением времени создание новых видов объектов всё более сложным

ммм, а как же модификатор static…
Если на функции навесить модификатор static в модуле (не в заголовке), то они перестанут быть доступны снаружи модуля. То есть, методами объекта станет невозможно пользоваться. Это очевидным образом разрушает идею объекта как полезной сущности.
Спасибо, очень доступное объяснение. Статья заслуживает больше плюсов!
Sign up to leave a comment.

Articles