FrontenderMagazine / programmirovanie-klassami-v-veb-prilozheniyakh

Программирование классами в веб-приложениях
http://frontender.info/programmirovanie-klassami-v-veb-prilozheniyakh/
1 stars 2 forks source link

Комментарии #1

Open FMRobot opened 9 years ago

a-wart commented 9 years ago

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

прочитав заголовок, я ждал описания ES6 классов, ну или хотя бы небольшой статьи про сахар class в CoffeeScript. В общем, рассказать про конструкторы, создание объектов и прототипы это хорошо, называть это популистским термином «программирование классами в веб-приложениях» — плохо. Плохо, потому что в js на текущий момент НЕТ классов, но есть прототипы. Плохо путать людей и называть синее мягким.

SilentImp commented 9 years ago

Материалы про классы в es6 будут несколько позднее. Что касается терминологии — мне кажется, что точность терминологии начинает играть роль, когда ты уже знаешь какие могут быть подходы к ООП в js. А когда ты им вообще не пользуешься — большой роли это не играет.

На практике достаточно редко можно увидеть нормальное ооп в js. Я говорю и о прототипном, и о попытке имитации классов в строго-типизированных языках, и о классах es6 в том числе. Мне часто приходится видеть чужой код. И — все грустно. Так что меня, например, эта статья порадовала.

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

LeusMaximus commented 9 years ago

А как лучше упростить создание экземпляров класса http://prntscr.com/7kfceh ? Чтобы не писать для каждого продукта отдельно?

vyushin commented 9 years ago

@LeusMaximus, лучше написать новый метод в ProductCollection, который будет добавлять продукты массивом.

Я сделал пример на CodePen. http://codepen.io/vyushin/pen/oXoBqx

ogonkov commented 9 years ago

Что это за сеньор, пихающий шаблоны в модель?

vyushin commented 9 years ago

@ogonkov, примеры максимально простые, чтобы лучше понять тему. Клиентская шаблонизация - это отдельная большая тема.

Конечно в боевых условиях модель и шаблоны надо разделять.

vyushin commented 9 years ago

@SilentImp, я тоже редко встречаю подобный подход в повседневной разработке! У меня пока нет точного ответа почему так происходит, но это правда грустно. По большей части это встречается во фреймворках и API. Например Backbone, Ext JS, Ymaps API и т. п.

Такой подход медленнее на старте, но зато потом легче поддерживать приложение.

fpinger commented 9 years ago

JavaScript устроен таким образом, что все в нем является объектами.

Например null или undefined? Мало того: значения типов string, number и boolean то же не являются объектами, а только ведут себя так иногда (такая встроенная магия).

var bar = "Вася";
bar.foo = "Пертрович" ;
// Скрытая магия:
// bar = new String(bar);
// bar.foo = "Пертрович" ;
// bar = bar.toString();
// А следоватешльно
console.log(bar);
// Вася
console.log(bar.foo);
// undefined

Использовать String, Number и Boolean вообще стоит ограничено, если вообще стоит. То есть если ты решил заняться разработкой на JS, то до всяких имитаций ООП, используя прототипное наследование, нужно ознакомится с http://bonsaiden.github.io/JavaScript-Garden/ru/

vyushin commented 9 years ago

@fpinger,

Например null или undefined?

Постараюсь выразить свою мысль в коде:

console.log(typeof null) // object
console.log(typeof new Boolean(true)) // object
console.log(typeof new Number(1)) // object
console.log(typeof new String('1')) // object
console.log(typeof new Array([1, 2])) // object

http://codepen.io/anon/pen/oXooOY

a-wart commented 9 years ago

@vyushin typeof'у ж нельзя верить. null это не объект. Результат typeof null == "object" — это официально признанная ошибка в языке, которая сохраняется для совместимости. На самом деле null — это не объект, а отдельный тип данных. И в целом, согласен с @fpinger — использовать Number String и Boolean в принципе антипаттерн, неспроста мдн и прочие js garden’ы настоятельно рекомендуют использовать эти примитивы в обход конструкторов

vyushin commented 9 years ago

@a-wart, JS слаботипизированный язык:

1 == new Number(1) // true
1 === new Number(1) // false

Вы говорите о типах, а я говорю про объекты. Не путайте, прошу вас. Это разные понятия.

a-wart commented 9 years ago

@vyushin вы утверждаете, что «всё в js является объектами». мы говорим: нет, не всё. например, null вы говорите: console.log(typeof null) // object мы говорим: это признанная ошибка языка и на самом деле null это не объект. вы говорите, что мы что-то путаем. я не вижу путаницы в своих рассуждениях, к сожалению, только в ваших.

и раз уж вы применяете в своём примере typeof то тоже говорите о типах.

vyushin commented 9 years ago

@a-wart, Вы правы, успокойтесь. В JS не всё является объектами, например (), {}, [] в JS не являются объектами. Запятые, символы +, -, =, : в JS не являются объектами. Я пропустил какой-то символ? :)

a-wart commented 9 years ago

@vyushin я спокоен, не переживайте. Боюсь, вы пропустили целостное понимание того, о чём пытаетесь писать. В остальном претензий не имею.

DeLaGuardo commented 9 years ago

Уточнения ради, все-таки {} и [] в JS являются обьектами

vyushin commented 9 years ago

@DeLaGuardo, а так }{, ][ ? ))

DeLaGuardo commented 9 years ago

@vyshin, Вы что-то пытаетесь этим доказать? Не понимаю, правда, что :)

DeLaGuardo commented 9 years ago

В JavaScript более распространено такое понятие как функции-конструкторы, но для удобства я буду называть их классами.

Итак, ООП... базовыми понятиями ООП являются наследование и инкапсуляция. Сделайте пожалуйста функцию-конструктор, которая будет наследована от другой функции-конструктора частично переопределяя ее функционал. Потом "для удобства" называйте ее классом, пока вы этого не сделаете - пожалуйста, даже не так - умоляю!! не смешивайте эти два понятия.

fpinger commented 9 years ago

@vyshin, если вас задела фраза:

То есть если ты решил заняться разработкой на JS

То прошу извинения, но она к абстрактному начинающему разработчику на JS, а не лично к вам. Я, думаю, она повлияла на градус эмоций.

Если null объект, то покажите мне его родословную, как объекта :)

vyushin commented 9 years ago

@DeLaGuardo, это базовые вещи. :) Функции-конструкторы поддерживают наследование через прототип.

DeLaGuardo commented 9 years ago

@vyushin, частичное, я говорил про частичное наследование

vyushin commented 9 years ago

@DeLaGuardo, опять же через прототип. :) Можно расширить один прототип другим прототипом, можно каким-то конкретным методом. Пожалуйста, в JS это есть. Пользуйтесь на здоровье. :)

vyushin commented 9 years ago

@fpinger, Если вам не по душе моя терминология, то я не стану вас переубеждать. :) Кто смог понять идею статьи целиком, не придираясь к отдельным конкретным словам, тому респект и уважуха, кто её не понял - очень жаль.

fpinger commented 9 years ago

@vyshin, я не против понятного кода, но при этом я за правильное понимание JS. :)

SilentImp commented 9 years ago

@vyushin В JS есть простые типы, такие как число или строка, но есть и объекты — число и строка. Если попытаться скажем использовать метод объекта строка для переменной простого типа строка, то из неё будет создан объект типа строка и метод будет вызван.

Про типы, кстати, достаточно подробно написано в спецефикации ECMA. И правила их преобразования тоже.

SilentImp commented 9 years ago

Так что да, «все в JS — объект» это преувеличение с формальной точки зрения.

vyushin commented 9 years ago

@SilentImp, конечно преувеличение. Ведь символы }, {, [, ], +, -, = и т. д. не являются объектами. :)

fpinger commented 9 years ago

@vyushin, литералы могут объявлять как объекты, так и не объекты. Но ведь речь не об этом.

vyushin commented 9 years ago

@fpinger, вы изучаете английский? Так вот, в английском языке одни и те же слова имеют разный смысл в зависимости от контекста. Тут то же самое. Перестаньте придираться к словам и смотрите на контекст. Что за детский сад?

fpinger commented 9 years ago

@vyushin, кстати относительно объектного подхода. А вы пробовали функциональный? В JS он позволяет писать ещё более понятный код, чем объектно ориентированный. :)

iamstarkov commented 9 years ago

@fpinger 👍 за фп! мне нравится ramda, а вам?

fpinger commented 9 years ago

@iamstarkov, спасибо за информацию. Добавил в тудушку посмотреть. Честно. я в теме фп недавно.

alexeyraspopov commented 9 years ago

Сделайте пожалуйста функцию-конструктор, которая будет наследована от другой функции-конструктора частично переопределяя ее функционал. Потом "для удобства" называйте ее классом, пока вы этого не сделаете - пожалуйста, даже не так - умоляю!! не смешивайте эти два понятия.

function Parent() {}

Parent.prototype.someMethodA = function(){};

Parent.prototype.someMethodB = function(){};

function Child() {}

Child.prototype = Object.create(Parent.prototype);

Child.prototype.someMethodA = function(){};

Теперь можно называть классом, да? :)

ditransler commented 9 years ago

Статья мне понравилась. Было интересно посмотреть, как одна и та же задача выполняется с помощью разных подходов (в зависимости от уровня разработчика). Себя смело причисляю к разряду Junior'ов.

Поводу высказывания "JavaScript устроен таким образом, что все в нем является объектами." и дальнейшего обсуждения хочу сказать, что уже не в первом источнике говорится об обратном. Например, в "Eloquent JavaScript" (http://eloquentjavascript.net/04_data.html#h_mT4YQfwHp6):

"Values of type string, number, and Boolean are not objects, and though the language doesn’t complain if you try to set new properties on them, it doesn’t actually store those properties. The values are immutable and cannot be changed."

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

vyushin commented 9 years ago

@ditransler, спасибо. :) Если кому-то нравится копать глубоко, то это личное дело каждого. Некоторым вообще нравится на ассемблере писать. Да ради Бога! Пусть хоть на голове стоят.

Есть натуральное число 9. Ну да - это число. Есть строка "I'm a string!". Да - это строка. Есть булев тип и т. д. Да, да, да. Это всё так. Это типы и они есть. Никто не говорил, что типов не существует и что типы - это объекты. Не надо придираться к слову "всё", я вас очень прошу.

0; // это число
"I'm a string"; // Это строка
true; // Булев тип

Речь не о том. Со всеми этими типами так или иначе мы взаимодействуем, как с объектами. Не всегда (а то опять скажете, что слишком обобщаю), понятное дело. Это само собой разумеется! Если мы работаем с ними, как с объектами, то имеем полное право назвать их объектами. И я буду называть их ОБЪЕКТАМИ. По тому что я работаю с ними, как с ОБЪЕКТАМИ и рассказываю о них, как об ОБЪЕКТАХ.

var str = "I'm a string"; // Это строка. Тип "string". Но у нее есть методы. Значит это объект.
str.toUpperCase(); // Вызываем метод ОБЪЕКТА String

Другой пример:

var num = 671; // Это натуральное число. Тип "number". Но у него есть методы. Значит это объект.
num.toString(); // Вызываем метод ОБЪЕКТА Number

Есть и третий пример:

var str = "I'm a string"; 
str.substr(1, 2); // Передаваемые аргументы 1 и 2 не являются объектами. Это целые числа.

Какой вывод мы можем сделать? В JavaScript представление типов может быть как в натуральном виде, так и в виде объектов. Вот и разобрались.

KarelWintersky commented 9 years ago

Здравствуйте. У меня глупый вопрос :) Senior developer создал очень интересную конструкцию. А потом вызвал её для трех продуктов. Создал три экземпляра объекта.

А что делать, если у нас 50 товаров? Создавать для каждого экземпляр: ... = new Product({ ... }); ? А если 500? А если 10000 ?

Ой, что у нас с потреблением памяти-то будет твориться...

Да, я теперь понимаю, почему современные веб-страницы так дико тормозят на моем стареньком ноуте! Упоение технологиями без оглядки на реальность.

vyushin commented 9 years ago

@KarelWintersky, хороший вопрос и правильный. Выше в комментах я говорил о методе addProducts для добавления товаров одним массивом. Это хардкодный вариант просто для наглядности. В реальности лучше подгружать этот массив аяксом с сервера в json или XML формате.

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

sergiivelykodnyi commented 9 years ago

По поводу "Объектов" и "Необъектов". Я думаю что лучше вещи называть своими именами, чтобы не сбивать с толку людей, которые только начали изучать JS. Строка это строка, она не есть объект, но если мы на ней вызываем метод объекта String, то парсер автоматически, на лету, создает объект обвертку, чтобы выполнить метод, но с самой строкой ничего не происходит, она остается неизменной. То что, со строкой можно обращаться как с объектом, это еще не значит, то ее можно называть объектом.

iamstarkov commented 9 years ago

срочно необходимо понизить градус дискуссии someone-is-wrong

KarelWintersky commented 9 years ago

@vyushin,

В реальности лучше подгружать этот массив аяксом с сервера в json или XML формате.

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

Потому и назвал ситуацию "упоением от технологий". Я внимательно изучил текст, вынес кое что интересное для себя и решил остановиться на втором варианте. Осознанно :)

В реальности лучше подгружать этот массив аяксом с сервера в json или XML формате.

Отлично :) Но ведь мы потом все равно проходим по этому массиву и импортируем данные в память, пусть и в цикле. Да, код страницы меньше. Но я говорю про потребление оперативки и cpu-time.

Как жить с таким?

Вопросы пагинации оставим в стороне: "Клиент должен видеть все доступные ему товары, никакой пагинации" - я такое слышал не раз.

Аякс-скроллинг - не панацея. Да, изначально на странице товаров мало и мало объектов. А когда мы пролистаем вниз? Мы же не можем убрать объекты из памяти только потому, что они оказались за пределами browser.viewport ?!

Похожая ситуация получается, когда мы просматриваем архив (ре)постов тумблер-блога. Но там то, хоть и используется аякс-скроллинг - просто добавляются элементы в DOM. Просто элементы, просто в DOM (хоть и превьюшки картинок/постов). Тем не менее, на каком-то этапе инстанс хрома улетает далеко за 800 мегов.

Нормально ли это? Не думаю. Что с этим делать? Не знаю.

alexeyraspopov commented 9 years ago

Как жить с таким?

Мы* решаем проблемы бизнеса, а не дрочим на байты.

*ответственные разработчики.

iamstarkov commented 9 years ago

байты, а особенно много-много байтов это проблемы клиентов, а соответственно и проблемы бизнеса

vyushin commented 9 years ago

@alexeyraspopov, сняли с языка выражение "байтодротство". :)

@KarelWintersky, желаю вам удачи в экономии байтов и ЦПУ. Родина вас не забудет.

KarelWintersky commented 9 years ago

@iamstarkov :+1: Осталось провести тесты и посрамить оппонентов.

@vyushin, кто с ассемблера начинал, всегда помнит о байтах и ЦПУ.

vyushin commented 9 years ago

@KarelWintersky, ахах. Во всем есть крайности. Думаю люди, которые не впадают в крайности способны сосредоточиться на более важных вещах и решить поставленные задачи более качественно в кратчайшие сроки.

KarelWintersky commented 9 years ago

@vyushin, вы отстаиваете позицию "подход сениора более качественный и занимает меньше времени разработки"? :)

sergiivelykodnyi commented 9 years ago

Все зависит от того для чего и кого создается приложение. Если это бизнес, то там все очень просто, нет клиентов, нет бизнеса. Например, не зря же написаны JS библиотеки для поддержки старых, и горячо любимых всеми разработчиками, браузеров ІE.

vyushin commented 9 years ago

@KarelWintersky, не совсем. Я считаю, что подход сениора более медленный на старте, но в долгосрочной перспективе полностью оправдывает себя. Тем более для команды разработчиков.

KarelWintersky commented 9 years ago

Мы оперируем данными с веб-страницы и используем строковую математику.

Мне кажется, подход миддла некорректен. Подозреваю, автор совершил эту ошибку намеренно - внёс селектор внутрь init()

init: function(selector) {
   $(selector).each(function() { ...  });
}

и productDiscount.init('.products li' );

не зря же написаны JS библиотеки для поддержки старых, и горячо любимых всеми разработчиками, браузеров ІE.

Совсем недавно друг допиливал внутренний портал для одного крупного российского банка. С большим трудом ему удалось убедить заказчика, что IE6 поддерживать не надо. В ответ его обязали поддерживать IE7. Почему? Потому что IE7 внутри локальной сети банка - _стандарт_. Мнение разработчика никого не интересует.

KarelWintersky commented 9 years ago

@iamstarkov: сильно мешает .comments form textarea { resize: none; }