Статьи

Какие учебники не говорят вам: как подходить к проектам

Что учебники не говорят вам

Я часто слышу, что люди, которые следуют учебным пособиям, оказываются неспособными подходить к проектам JavaScript самостоятельно.

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

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

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

Важное примечание: по мере прохождения этой статьи вы увидите несколько примеров кода. Если какие-то из них кажутся новыми или незнакомыми, пока можно их просмотреть. Цель этой статьи — помочь вам понять общий процесс подхода к проекту, а не отвлекаться на технические детали.

Сначала освоитесь с основами

Как минимум, вы захотите ознакомиться с некоторыми основами JavaScript (и программированием в целом). Это может включать переменные, функции, операторы if, циклы, массивы, объекты, методы манипулирования DOM, такие как getElementById , querySelectorAll и innerHTML . Вы можете просмотреть их в Google или посмотреть их на MDN, когда закончите с этой статьей.

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

Многие люди проходят этот шаг, и в результате все занимает больше времени. Это все равно что пытаться играть на 3-м уровне видеоигры, не освоившись с элементами управления на 1-м уровне. Много недовольных.

Составить план

Как JavaScript проекты происходят

Вместо того, чтобы прыгать и пытаться сделать ваш проект в виде серии линейных шагов, сначала найдите время, чтобы взглянуть на общую картину. Составьте общий план. Какие вещи должны произойти? Например, если вы пытаетесь создать часы обратного отсчета, вам может понадобиться способ измерения времени, место для хранения данных, где-то для отображения чисел и, возможно, способ управления часами.

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

Напишите это без кода

Теперь, когда у вас есть свой план, вы захотите выяснить детали. Мой любимый способ сделать это — написать конкретно, что вы хотите, чтобы каждая часть вашего проекта делала. Ключ должен написать это не в коде, а на простом языке. (Это называется псевдокодом .) Таким образом, вы можете четко думать о том, что делает ваш проект, не отвлекаясь на детали синтаксиса.

Для часов обратного отсчета ваши заметки могут выглядеть примерно так:

  • Получить текущее время
  • Укажите время окончания
  • Найти разницу между текущим временем и временем окончания, чтобы получить оставшееся время
  • Повторно получить оставшееся время для каждого шага обратного отсчета
  • Показать оставшееся время на экране на каждом этапе обратного отсчета

Вы можете разбить отдельные части на более мелкие, например:

  • Показать оставшееся время на экране на каждом этапе обратного отсчета
    • Разделите время на часы, минуты, секунды
    • Показать часы в одном контейнере
    • Сделайте то же самое в течение нескольких минут и секунд

Как только у вас есть логика, вам будет гораздо легче писать код. Это потому, что проще написать код для конкретного шага, такого как «вычесть текущее время из времени окончания», чем написать код для всего проекта, например «построить часы обратного отсчета».

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

Построить маленькие кусочки

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

 const currentTime = new Date().getTime(); console.log(currentTime); 

Как только вы будете удовлетворены, вы можете получить время окончания обратного отсчета:

 const endTime = new Date(2017, 4, 4, 7, 30).getTime(); console.log(endTime); 

Когда вы делаете свои собственные часы, вы можете выбрать конкретную дату окончания, как в примере кода выше, но, поскольку я не хочу, чтобы код в этой статье перестал работать после определенной даты, я собираюсь установить конец вместо этого через 10 дней (обратите внимание на преобразование 10 дней в миллисекунды, поскольку это единицы измерения, которые использует JavaScript):

 const endTime = new Date().getTime() + 10*24*60*60*1000; console.log(endTime); 

Вот некоторые преимущества написания вашего кода небольшими кусочками:

  • Вы получаете возможность убедиться, что отдельные части функционируют, прежде чем переходить к следующим шагам.
  • Проще подумать о том, что вы делаете, когда вас не отвлекает слишком много движущихся частей одновременно.
  • Вы будете двигаться быстрее, потому что вы не пытаетесь отслеживать миллион вещей одновременно.
  • Так намного легче обнаружить и предотвратить ошибки.
  • Вы можете экспериментировать и учиться по мере необходимости.
  • Вы часто будете в конечном итоге писать полезные фрагменты кода, которые вы можете использовать в другом месте.

Положить кусочки вместе

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

Например, вот как вы можете сложить время начала и время окончания, чтобы вычислить оставшееся время в часах обратного отсчета:

 // set our end time const endTime = new Date().getTime() + 10*24*60*60*1000; // calculate remaining time from now until deadline function getRemainingTime(deadline){ const currentTime = new Date().getTime(); return deadline - currentTime; } // plug endTime into function to output remaining time console.log(getRemainingTime(endTime)); 

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

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

HTML:

 <div id="clock"></div> 

JavaScript:

 // set our end time const endTime = new Date().getTime() + 10*24*60*60*1000; // calculate remaining time from now until deadline function getRemainingTime(deadline){ const currentTime = new Date().getTime(); return deadline - currentTime; } // store clock div to avoid repeatedly querying the DOM const clock = document.getElementById('clock'); // show time repeatedly function showTime(){ const remainingTime = getRemainingTime(endTime); clock.innerHTML = remainingTime; requestAnimationFrame(showTime); } requestAnimationFrame(showTime); 

В приведенном выше примере мы добавили функцию showTime которая отображает оставшееся время на экране. В конце функции мы включаем requestAnimationFrame(showTime) , который в основном говорит, showTime снова запустите showTime как только браузер будет готов. Это позволяет нам постоянно обновлять отображение времени с высокой производительностью .

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

Используя подходы, которые вы уже изучили (небольшие шаги и т. Д.), Вы можете сначала преобразовать миллисекунды в секунды, посмотреть, как это выглядит, и вставить это в свою функцию. Затем вы можете повторить этот процесс для подсчета минут, часов и дней. Конечный результат может выглядеть примерно так:

 function showTime(){ const remainingTime = getRemainingTime(endTime); const seconds = Math.floor((remainingTime/1000) % 60); const minutes = Math.floor((remainingTime/(60*1000)) % 60); const hours = Math.floor((remainingTime/(60*60*1000)) % 24); const days = Math.floor(remainingTime/(24*60*60*1000)); clock.innerHTML = `${days}:${hours}:${minutes}:${seconds}`; requestAnimationFrame(showTime); } requestAnimationFrame(showTime); 

Эксперимент и тест

К этому моменту в вашем проекте вы проведете множество экспериментов и тестов, чтобы убедиться, что все работает. Как только это сработает, посмотрите, сможете ли вы его сломать. Например, что если пользователь нажимает здесь или там? Что если один из входов неожиданный? Что делать, если размер экрана узкий? Все ли работает в ожидаемых браузерах? Есть ли более эффективный подход к какой-либо части этого проекта?

Возвращаясь к нашему примеру с часами обратного отсчета, что произойдет, если таймер достигнет нуля? Мы можем добавить оператор if, чтобы убедиться, что часы останавливаются на нуле:

 function showTime(){ ... // ensure clock only updates if a second or more is remaining if(remainingTime >= 1000){ requestAnimationFrame(showTime); } } 

Обратите внимание, что причина, по которой мы использовали 1000 миллисекунд (1 секунду) в этом случае, состоит в том, что если бы мы использовали ноль, то тактовая частота перескочила бы и в конечном итоге составила -1 Если ваши часы используют меньшие единицы, чем секунды, тогда сделайте конечное условие меньше одной секунды.

Хороший друг указал на эту проблему, когда я работал над этой статьей, и это просто еще один пример того, как код может не получиться идеальным в первый раз.

Это прекрасно ведет к следующему пункту.

Получить внешнюю помощь

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

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

Инструменты и методы меняются, но навыки обучения не исчезают.

Рефакторинг вашего кода

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

Ваш код лаконичен и читабелен?

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

Ваш код эффективен?

Например, если вы ищете в своем документе один и тот же элемент снова и снова, вы можете вместо этого сохранить элемент в переменной, чтобы ваш код выполнял меньше работы. Мы уже сделали это в нашем примере с обратным отсчетом времени:

 // store clock div to avoid repeatedly querying the DOM const clock = document.getElementById('clock'); 

Вы использовали четкие имена для своих функций и переменных?

Например, имя функции, например showTime , будет намного понятнее, чем st . Это важно, потому что люди часто называют вещи, думая, что они имеют смысл, и затем они теряются позже, потому что они забыли, что означали их сокращения. Хороший тест для ясности — нужно ли вам слишком много объяснять имя кому-то, кто не знаком с кодом.

Есть ли потенциальные конфликты именования?

Например, используете ли вы такие имена, как «контейнер», которые, скорее всего, будут использоваться в других местах?

Вы загрязняете глобальную область слишком большим количеством переменных?

Один из простых способов защиты глобальной области видимости — бросить код часов обратного отсчета во IIFE ( выражение функции, вызываемое немедленно ). Таким образом, часы могут получить доступ ко всем своим переменным, но больше ничего не может.

 (function(){ // code goes here })(); 

Вызвал ли процесс редактирования какие-либо ошибки?

Например, вы изменили имя переменной в одном месте, не изменяя его везде? Вы добавили что-то к объекту, но забыли добавить лишнюю запятую?

Нужно ли полировать вывод?

В нашем примере с часами обратного отсчета было бы неплохо увидеть ведущие нули (10:09 вместо 10: 9). Одним из способов было бы увидеть, если число меньше 9, а затем поставить перед ним «0», но это довольно долго. Однажды я видел пример кода, в котором был хитрый трюк, который заключался в добавлении «0» впереди, а затем с использованием slice(-2) чтобы просто взять последние две цифры, несмотря ни на что. Изменения сделали бы наш код похожим на это:

 function showTime(){ const remainingTime = getRemainingTime(endTime); const seconds = ('0' + Math.floor((remainingTime/1000) % 60)).slice(-2); const minutes = ('0' + Math.floor((remainingTime/(60*1000)) % 60)).slice(-2); const hours = ('0' + Math.floor((remainingTime/(60*60*1000)) % 24)).slice(-2); const days = ('0' + Math.floor(remainingTime/(24*60*60*1000))).slice(-2); clock.innerHTML = `${days}:${hours}:${minutes}:${seconds}`; // ensure clock only updates if a second or more is remaining if(remainingTime >= 1000){ requestAnimationFrame(showTime); } } requestAnimationFrame(showTime); 

Ваш код излишне избыточен?

Вы повторяете код, который может быть вместо функции или цикла? Со ссылкой на вышесказанное, мы могли бы переместить код, чтобы добавить дополнительный ноль к выводу в его собственную функцию. Это уменьшает дублирование и облегчает чтение.

 function pad(value){ return ('0' + Math.floor(value)).slice(-2); } const seconds = pad((remainingTime/1000) % 60); 

Поможет ли это посмотреть на этот проект свежими глазами?

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

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

Через несколько месяцев вы оглянетесь назад и поймете, что могли бы сделать его намного лучше. Как мудро сказал мой друг, это хорошо; это означает, что вы делаете успехи.

Если вам интересно, вот живая демонстрация примера часов (с некоторыми добавленными стилями):

резюмировать

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

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

Эта статья была рецензирована Vildan Softic и Matt Burnett . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!