16. JS с нуля, ваще с нуля (if-else-if-else)

Оценить качество материала и подачу материала автором видео:

Front-end

Трудоустройтесь middle front-end разработчиком на React JS (TypeScript) за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Front-end

Back-end

Трудоустройтесь middle back-end разработчиком за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Back-end

Карьерный бустер

Получите коммерческий опыт на реальных стартапах, прокачайте tech & soft навыки, научитесь работать в команде, проходить собеседования и получите первую работу в IT!

Перейти на курс
Карьерный бустер

Основы Front-end

Сделайте первый шаг в IT, освоив базовые знания разработки и научившись создавать небольшие проекты на JavaScript

Перейти на курс
Основы Front-end

Основы Back-end

Сделайте первый шаг в IT, освоив базовые знания разработки. Без опыта. Без математики. Только практика: JavaScript, SQL, Node JS, база данных

Перейти на курс
Основы Back-end

if...else

Автор конспекта: Андрей Шамара

Оптимизация JavaScript и условные конструкции

Этот раздел посвящен улучшению и оптимизации JavaScript кода, а также введению в условные конструкции if-else-if-else.

Начальный код

  • index.html
index.html
<div class="jskmb-calculator">
  <div class="operations-block">
    <button id="buttonPlus">+</button>
    <button id="buttonMinus">-</button>
    <button id="buttonMultiply">*</button>
    <button id="buttonDivide">/</button>
  </div>
  <div class="separator">
    <hr />
  </div>
  <div class="inputs-block">
    <div class="input-block">
      <label>Number 1</label>
      <input type="number" id="number1" />
    </div>
    <div class="input-block">
      <label>Number 2</label>
      <input type="number" id="number2" />
    </div>
  </div>
</div>
  • index.js
index.js
// Получаем ссылки на кнопки
var buttonPlus = document.getElementById("buttonPlus")
var buttonMinus = document.getElementById("buttonMinus")
var buttonMultiply = document.getElementById("buttonMultiply")
var buttonDivide = document.getElementById("buttonDivide")
 
function onButtonPlusClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 + number2
  window.alert(sum)
}
 
function onButtonMinusClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 - number2
  window.alert(summ)
}
 
function onButtonMultiplyClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 * number2
  window.alert(summ)
}
 
function onButtonDivideClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 / number2
  window.alert(summ)
}
 
// Назначаем обработчики событий
buttonPlus.addEventListener("click", onButtonPlusClick)
buttonMinus.addEventListener("click", onButtonMinusClick)
buttonMultiply.addEventListener("click", onButtonMultiplyClick)
buttonDivide.addEventListener("click", onButtonDivideClick)

Ключевые темы

1. Сокращение дублирования кода и глобальные переменные

Глобальные переменные могут быть "злом" в больших проектах! Используйте их с осторожностью.

  • Проблема дублирования: Изначально в коде четыре функции-слушателя, выполняющие схожие действия, что приводит к повторению кода, особенно в части получения элементов DOM по их ID.
index.js
function onButtonPlusClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 + number2
  window.alert(sum)
}
 
function onButtonMinusClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 - number2
  window.alert(summ)
}
 
function onButtonMultiplyClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 * number2
  window.alert(summ)
}
 
function onButtonDivideClick() {
  var input1 = document.getElementById("number1")
  var input2 = document.getElementById("number2")
 
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 / number2
  window.alert(summ)
}
  • Решение (Глобальные переменные): Объявление переменных input1 и input2 за пределами функций делает их глобальными. Это позволяет избежать повторного поиска элементов DOM внутри каждой функции.
index.js
// Получаем элементы из DOM
const input1 = document.getElementById("number1")
const input2 = document.getElementById("number2")
 
function onButtonPlusClick() {
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 + number2
  window.alert(sum)
}
 
function onButtonMinusClick() {
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 - number2
  window.alert(summ)
}
 
function onButtonMultiplyClick() {
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 * number2
  window.alert(summ)
}
 
function onButtonDivideClick() {
  var number1 = Number(input1.value)
  var number2 = Number(input2.value)
 
  var summ = number1 / number2
  window.alert(summ)
}
  • Нюанс: Глобальные переменные увеличивают вероятность коллизий имен и усложняют отладку. В данном контексте это было приемлемым упрощением для демонстрации.
  • Проверка после рефакторинга: Важно всегда проверять работоспособность приложения после каждого шага рефакторинга.
👉

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

2. Динамическое получение значений (проблема value и number)

  • Проблема value: Присвоение value из инпута переменной при загрузке страницы приводит к тому, что эта переменная содержит пустое значение (""), которое затем преобразуется в 0 при попытке математических операций.
index.js
// Получаем элементы из DOM
const input1 = document.getElementById("number1")
const input2 = document.getElementById("number2")
 
// Получаем значения элементов из DOM
var number1 = Number(input1.value)
var number2 = Number(input2.value)
 
function onButtonPlusClick() {
  var summ = number1 + number2
  window.alert(sum)
}
 
function onButtonMinusClick() {
  var summ = number1 - number2
  window.alert(summ)
}
 
function onButtonMultiplyClick() {
  var summ = number1 * number2
  window.alert(summ)
}
 
function onButtonDivideClick() {
  var summ = number1 / number2
  window.alert(summ)
}
⚠️
Выполняя эти функции в операндах будут значения 0
  • Решение: Значения из инпутов (number или value) должны быть получены непосредственно в момент их использования (например, при нажатии на кнопку операции), а не заранее. Это гарантирует актуальность данных.

3. Инкапсуляция получения и преобразования чисел (getNumber функция)

  • Проблема: Повторяющийся код для получения значения из DOM-элемента и его преобразования в число.
  • Решение: Создание функции getNumber (например, getNumber1, getNumber2), которая инкапсулирует эти шаги.
  • return: Оператор return возвращает результат выполнения функции, позволяя использовать его в другом месте кода.
  • Немедленное использование результата: Вместо сохранения результата функции getNumber в промежуточную переменную, можно использовать его напрямую в выражении (например, getNumber1() + getNumber2()). Это еще больше сокращает код.
index.js
// Получаем элементы из DOM
const input1 = document.getElementById("number1")
const input2 = document.getElementById("number2")
 
// Функция для получения первого числа
function getNumber1() {
  return Number(input1.value)
}
 
// Функция для получения второго числа
function getNumber2() {
  return Number(input2.value)
}
 
// Функция для выполнения операции сложения
function makeOperation(operationCode) {
  var result = getNumber1() + getNumber2()
 
  window.alert(result)
}
 
function onButtonPlusClick() {
  makeOperation("+")
}
 
function onButtonMinusClick() {
  makeOperation("-")
}
 
function onButtonMultiplyClick() {
  makeOperation("*")
}
 
function onButtonDeviceClick() {
  makeOperation("/")
}
⚠️

Никогда не используйте функцию eval()! Это создает серьезные уязвимости безопасности.

🔗

Больше деталей о возможностях смотрите в документации eval()

4. Универсальная функция для операций (makeOperations)

  • Проблема: Дублирование логики для различных математических операций (сложение, вычитание, умножение, деление) в разных функциях-обработчиках событий.
  • Решение: Создание одной универсальной функции makeOperations, которая принимает operationCode (строку, представляющую операцию) в качестве параметра и использовать if-else-if-else конструкции для создания разветвленной логики.
  • Параметры функции: Параметры позволяют функции адаптировать свое поведение в зависимости от входных данных.
javascript
//Решение
function makeOperation(operationCode) {
  if (operationCode === "+") {
    var result = getNumber1() + getNumber2()
  } else if (operationCode === "-") {
    var result = getNumber1() - getNumber2()
  } else if (operationCode === "*") {
    var result = getNumber1() * getNumber2()
  } else if (operationCode === "/") {
    var result = getNumber1() / getNumber2()
  } else {
    window.alert("operation is unknown")
  }
  window.alert(result)
}
  • Оператор сравнения ===: Три знака равенства === используются для строгого сравнения (значение и тип).
  • Логика: Программа перестает быть полностью линейной и начинает выполнять разные ветки кода в зависимости от условий.
  • Обработка неизвестных операций: Добавление финального else для обработки случаев, когда operationCode не соответствует ни одному из ожидаемых значений.

5. Отладка с помощью DevTools

  • Точки останова (Breakpoints): Позволяют приостановить выполнение кода в определенной строке и исследовать состояние переменных. Полезно для понимания потока выполнения и отладки if-else логики.

devtools

🔗

Больше деталей о возможностях смотрите в документации Отладка в браузере

6. Дальнейшие улучшения (один слушатель событий)

  • Идея: Вместо четырех отдельных слушателей событий для каждой кнопки, можно использовать один слушатель, который будет определять, какая кнопка была нажата, и извлекать символ операции непосредственно из текста или атрибута кнопки. Это будет рассмотрено в следующем уроке.
javascript
// Пример реализации
 
// Получаем ссылки на кнопки
var buttonPlus = document.getElementById("buttonPlus")
var buttonMinus = document.getElementById("buttonMinus")
var buttonMultiply = document.getElementById("buttonMultiply")
var buttonDivide = document.getElementById("buttonDivide")
 
function onButtonClick(/*?*/) {
  /*?*/
}
 
// Назначаем один обработчик событий для всех
buttonPlus.addEventListener("click", onButtonClick)
buttonMinus.addEventListener("click", onButtonClick)
buttonMultiply.addEventListener("click", onButtonClick)
buttonDivide.addEventListener("click", onButtonClick)
style.css
/* Пример стилей для кнопок операций */
.operation-button {
  padding: 10px 15px;
  margin: 5px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background-color: #4caf50;
  color: white;
}
 
.operation-button:hover {
  background-color: #45a049;
}

Боевой маршрут (JS Ваще с нуля)

Видеоурок - 17 видео из 29