Как стать автором
Обновить

Комментарии 23

Что плохо в коде:
Груда кода в глобальном namespace. Зачем?
Не нужен флаг isIE, нужно проверять возможности, которые требуются, а не браузер.
Местами как-то странно используется JS (например, чтобы поместить элемент в начало массива можно использовать unshift).

Более подробно не смотрел.
Об этом, я, конечно, подумал, прежде чем дать именно такой код. Подумал вот что: не стоит переусердствовать в применении принципов (что сам по себе тоже принцип). Если код используется на данной странице и только на ней — что вы пишете? Глобальную переменную, не задумываясь о совместимости. Библиотеки и переносимые процедуры уже сами подумали о том, как уйти из [[Global Scope]]. Сделал это и я в объекте GameLife, но зачем переусердствовать в функциях на кнопках, если они только на этой странице? Поэтому всякие doXxxx..() — в глобальных переменных.

isIE — согласен, это по привычке, оно интуитивно понятно. Это как бы говорит: «а вот для IE поступим иначе». функция g() — это тоже, лёгкая замена $(). Есть в коде более серьёзный недостаток — функция initGL1(), на неё «не хватило сил» подойти объектно.
isIE — согласен, это по привычке, оно интуитивно понятно. Это как бы говорит: «а вот для IE поступим иначе»
Ну вот ровно вот это — плохой подход. Думаю, все хаки, которые вы использовали, уже не нужны в IE9, а он скоро выйдет.
При моём весьма положительном отношении к Вам лично я совершенно согласен с shpaker, bolk и razon.

Ваш код далёк от идеального и перечислять можно очень долго. Ошибки есть по всем ступеням — идеология кода, html-верстка, кучу ненужных кусков, ошибочных кусков, непонятных кусков, огромное количество комментариев.
Идеология ООП не в том, чтобы вынести всё классы. ООП и классы это всё-равно, что война и танки. Можно сделать войну без танков, а танки могут быть и без войны.
Если хотите написать такой код, который можно было бы называть примером для новичков следует очень много исправить.
А теперь — малая толика ошибок из разных областей, которые я заметил беглым проглядыванием.

Проблемы с html-кодом:

Многословный заголовок страницы. Стандарт html5 позволяет и рекомендует намного более изящную запись, не соблюдены отступы:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Заменяем на
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />


Кучу нарушений идеи ненавязчивого JavaScript.

Кое-где забыли скобки:
<div id=dGL></div>


Фактически, хотя вы и объявили доктайп xHTML, но у вас "6 Errors, 22 warning(s)". А еще кучу семантических и стилистических ошибок.

Проблемы с javascript-кодом:

Тут можно критиковать почти каждую строчку. Я начну с топика.

Давайте даже такую простую задачу оформим в лучших традициях ООП

Это далеко не лучшие традиции ООП и такой стиль никак не рекомендуемый для новичка.. Ниже аргументирую почему.

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

Нет, эффект размножения есть даже без наследования — а при обычном создании экземпляра класса. Но в данном случае создаётся не так много экземпляров, потому оно не играет критической роли. Другое дело, что вы утверждаете, что неокрепшие умы сочтут это хорошим стилем и правильной реализацией. Потому даже(тем-более!) в маленьких демонстративных примерах нельзя использовать такой способ.
Тем более, что из-за его использования у вас некрасиво смешались две области видимости, а в купе с однобуквенным наименованием переменных сделало код совершенно непонятным.

if(conf.w ==null) conf.w = 402; //параметры, не будут жить как замыкания
if(conf.h ==null) conf.h = 321;
if(conf.o ==null) conf.o = g('dbGL1');

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

Вы совершенно не соблюдаете стиль.
Почему this.cvs и this.gen объявлены с this, а w и h — с var?

Фигурные скобки совершенно не имеют закономерности расстановки. Кое-где они стоят в одну линию с условием, кое-где в следующей, кое-где развернутые, кое-где отсутствуют. Бардак, в общем.

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

То, что вы сделали с условиями в this.show — это не оптимизация, а кромешный ужас. Их надо было схлопнуть и ни в коем случае не оптимизировать. Тормозит явно не банальный «иф». Вы, блин, arc в цикле делаете, и при этом выносите if, увеличивая код в 3-4 раза! А полученный результат от этого — ускорение в 0.01%. Это если повезет.
Если бы вы написали нормальный код, который потом пропрофилировали, то поняли, что смысла выносить ифы нету совершенно.

Ошибка в плане скорости у вас не в месторасположении условий, а в архитектуре. Я сейчас делаю сверхтяжёлый код, с попиксельной отрисовкой канвы размером 480*225, кучей матана, риалтайм-ресайзом изображений и т.п., который, при этом, умудряется более-менее выдавать 20-30 фпс. Но там куда больше вычислений чем в вашем коде. В реализации «жизни» всё должно просто летать.

if(!isIE)
	o.querySelector('.gen #' + oId).innerHTML = val;
else
	g(oId).innerHTML = val;

Что это за кромешный ужас? oId впонле достаточно для уникальной идентификации элемента, зачем замедлять получение элемента, указывая проверку на принадлежность к классу?

Что случится в функции this.initCvs, если отсутствует метод querySelector?

Почему вы не закешировали результат document.getElementsByName('rule') в this.checkRule

Почему кое-где ссылки на dom-объекты передаются в GameLife аргументами, а кое-где — берутся из «Магических строк» прям внутри метода

Ад внутри условия if(mthd =='pre'){ остался для меня сущей загадкой. А перечитал его раз 5, но так и не понял, зачем он нужен. Между прочим, тут видно один из недостатков перегруженного конструктора — непонятно к какой области видимости относится какая переменная. Долго искал, где взялась o

Вообще названия переменных — приводят в ужас. Перечислю те, что есть в области видимости this.show
mthd, o, s, q, l, pi2, z2, z21, z3, z6, grid, rect, x, y
conf, o, GL, w, h, z, a, iStop, iStart, okr

И это только те, которые в локальной области видимости. При этом z21 = z/2.3 (где логика?), q — канвас-контекст, а okr — сокращение от русского слова «окружение».

Этот код не то что далёк от ООП — он вообще далек от хорошего кода. И то, что вы используете методы не делает его ООП.

Без слёз на него смотреть тяжело. И это и есть пример того самого ада, в который можно попасть при поддержке проектов на javascript.

Заключение

Если ничего не помешает, то, под влиянием от вашей статьи, я таки опубликую вариант «жизнь» на javascript best-practice кодом и подробным объяснением.

Если нужна помощь, можете написать мне в личку, обсудим.

спойлеров на хабре нет
Спойлер — это информация. То, что вы называете спойлером, можно назвать «катом» (cut), например.
Спо́йлер, англ. to spoil — «гадить», «отравлять», «портить». Я вам скажу хорошую вещь спойлером не назовут! А вот то шо вы назвали «катом» у хороших людей называется «обрезанием».
А если серьезно — автор прав, спойлеров порой ой как не хватает…
Автор не прав в том, что не эта вещь называется спойлером. Именно об этом мой комментарий.
НЛО прилетело и опубликовало эту надпись здесь
Дни «Жизни» на Хабре! :)
Сколько стало интересных статей на Хабре.
Вы лучше бы чем в пятый раз объяснять правила жизни на хабре, алгоритмы свои поописывали, а то лично мне такие строки:
GL.cvs.width = GL.cvs.width;

или такие условия
if(!GL.rect){
if(...){

}else{

}else{

}else{
...}
}

Как-то по индуски )) Без обид конечно код работает нормально, но вот исходники иногда заставляют улыбаться ))
Привет! Спасибо.
Ради алгоритмов и их обсуждения как раз было написано. И всему есть своё объяснение. (Думаю, каждый найдёт образцы подобного кода у себя.)

> GL.cvs.width = GL.cvs.width;
Почитайте (согласен, тут мне надо было написать комментарий) документацию к canvas, и будет ясно, что это далеко не бессмысленная строчка — это способ очистки полотна (!).

> canvas.width = canvas.width; // clears the canvas


Более явного способа очистки почему-то не наблюдается. Было бы лучше, конечно — что-то типа canvas.clear();.

Условия (при выводе канваса) — тоже очень нужная в данном случае вещь (это мне показалось очевидным, не стал комментировать в коде). Если бы я слепил их все в один цикл, а условия загнал внутрь, то цикл медленнее бы работал. Здесь — компромисс объёма кода и скорости выполнения.
Вообще-то существует clearRect()
canvas.width работает как минимум в 10 раз медленней, чем clearRect()
вот оно как
Я просто на канве обычно всё перерисовываю и поэтому как-то не задумывался о очистке её вообще, хотя можно было бы clearRect, но да такой как у вас способ оправданней наверное
Добавил в работающий код (и в статью) вариацию правил — Day & Night. Описана в ссылках [7] в Википедии (англ.). Довольно интересное поведение.
у меня кстати тоже есть Жизнь на канвасе писанная, я как разгребусь с делами выложу. Я там правда немного отсебятины в правила вносил ))
Если выложите как статью — предупредите и меня заранее, я ко времени её выкладки сделаю спрайты, чтобы оценить скорость выполлнения. Когда несколько новостей по одной теме, читается интереснее.
Давайте даже такую простую задачу оформим в лучших традициях ООП

Посмотрел код. Позвольте спросить, где в нем ООП?

Про кучу дублирования я вообще молчу
Про дублирование там, где надо максимально ускорить циклы, я уже писал в комментариях. ООП — в определении объекта — игрового поля и методов работы с ним. Если у Вас возникли более конструктивные предложения — пожалуйста, покажите, как надо делать. Иначе это не критика, а разговор ни о чём. С уважением…
Вместо того, чтобы издеваться над массивом(с постоянным перемещением в начало) можно было бы сделать два массива, которые менять местами. Один используется как источник для наполнения данными второго.
Но медлительность убивает. Все должно работать намного быстрее при должном подходе.
Шок в шоке ))
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории