Состояние (в JavaScript), объясненное приготовлением простой еды

Если вы когда-нибудь готовили еду дома, то можете понять, как писать код с отслеживанием состояния, используя методы объектно-ориентированного программирования на JavaScript.

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

Например, большинство людей начинают с большого количества Глобальный переменные или переменные, область действия которых находится на верхнем уровне файла. Они не являются частью какого-либо отдельного класса, объекта или функции.

Например, это глобальная переменная с именем государство:

let state = "global";

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

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

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

В этой статье описывается состояние в контексте React.популярная библиотека JavaScript.

Но знаете что? Даже состояние может доставить вам головную боль, когда ваш код усложнится! Изменение состояния может привести к непредвиденным последствиям.

Давайте остановимся прямо здесь. Государство является популярным инструментом в объектно-ориентированного программирования или ООП. Но многие программисты предпочитают функциональное программирование , что препятствует изменению состояния. JavaScript поддерживает обе парадигмы.

Ладно, сразу много терминологии. Я хотел найти способ показать, как ООП и функциональное программирование могут достигать одних и тех же целей, даже если функциональное программирование не использует государство.

В этом руководстве показано, как можно приготовить спагетти с соусом с точки зрения ООП и функциональности.

Вот краткий обзор двух разных подходов:

Давайте прыгнем в него. Чтобы понять этот учебник, вам просто нужно понять функции и объекты в JavaScript.

Объектно-ориентированный метод (с использованием состояния)

На графике выше мы показали два разных подхода к приготовлению макаронного ужина:

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

Объектно-ориентированный подход фокусируется на состояние обновления поэтому наш код будет иметь состояние на двух разных уровнях:

  1. Global, или состояние всей этой еды.
  2. Локальный для каждого объекта.

В этом руководстве мы будем использовать синтаксис ES6 для создания объектов. Вот пример глобального состояния и прототип «Горшок».

let stoveTemp = 500;

function Pot(){
  this.boilStatus = '';
  this.startBoiling = function(){
    if( stoveTemp > 400)
      this.boilStatus = "boiling";
  }
}

let pastaPot = new Pot();
pastaPot.startBoiling();

console.log(pastaPot);

Примечание. Я упростил оператор console.log, чтобы сосредоточиться на обновлении состояния.

Вот визуальное представление этой логики:

До

ИнициалБилСтатус.jpg

После

после кипячения пасты.jpg

Есть два состояния, и когда pastaPot создается с помощью прототипа Pot, изначально он имеет пустое состояние кипятка. Но тогда есть изменение состояния.

Мы запускаем pastaPot.startBoiling(), и теперь (местное государство) «кипит», так как глобальное состояние печиTemp более 400.

Теперь давайте сделаем еще один шаг. Мы позволим макаронам свариться из-за состояния pastaPot.

Вот код, который мы добавим к приведенному выше фрагменту:

function Pasta (){
  this.cookedStatus = false;
  this.addToPot = function (boilStatus){
    if(boilStatus == "boiling")
      this.cookedStatus = true;
  }
}

let myMeal = new Pasta();
myMeal.addToPot(pastaPot.boilStatus);

console.log(myMeal.cookedStatus);

Вау! Это много сразу. Вот что произошло.

  1. Мы создали новый прототип «Паста», где каждый объект будет иметь местное государство называется приготовленныйСтатус
  2. Мы создали новый экземпляр Pasta под названием myMeal.
  3. Мы использовали состояние из объекта pastaPot, созданного нами в последнем фрагменте, чтобы определить, следует ли нам обновить состояние, называемое CookStatus в myMeal, на приготовленное.
  4. Так как состояние кипения в pastaPot было «кипящее», наша паста теперь готова!

Вот этот процесс визуально:

До

Pastapotstate1.jpg

После

пастапотштат2.jpg

Итак, теперь у нас есть локальное состояние одного объекта, которое зависит от локального состояния другого объекта. И это локальное состояние зависело от некоторого глобального состояния! Вы можете видеть, как это может быть сложно. Но, по крайней мере, сейчас это легко проследить, поскольку состояния обновляются явно.

Функциональный метод (без состояния)

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

Функциональное программирование имеет две основные ценности, которые отличают его от ООП: неизменность и чистые функции.

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

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

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

Вот пример функции, которая будет варить макароны.

const stoveTemp = 500;

const cookPasta = (temp) => {
  if(temp > 400)
    return 'cooked';
}

console.log(cookPasta(stoveTemp));

Этот код успешно вернет строку «приготовлено». Но обратите внимание — нет объекта, который мы обновляем. Функция просто возвращает значение, которое будет использоваться на следующем шаге.

Вместо этого мы сосредоточимся на входных и выходных данных одной функции: cookPasta.

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

Вот как это выглядит.

Думайте об этом как о «просмотре временной шкалы» для продвижения еды — эта конкретная функция охватывает только первую часть, переход от сухих макарон к приготовленным макаронам.

Теперь давайте покроем вторую часть, как подается еда. Вот код, который будет подавать еду. Он появится после блока кода выше.

const serveMeal = (pasta) => {
 if (pasta == 'cooked')
   return 'Dinner is ready.'
}

console.log( serveMeal(cookPasta(stoveTemp)) );

Теперь мы передаем результаты функции cookPasta непосредственно в функцию serveMeal. Опять же, мы можем сделать это без изменения состояния или структуры данных.

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

Заинтересованы в дополнительных визуальных уроках?

Если вы хотите прочитать больше наглядных руководств по HTML, CSS и JavaScript, ознакомьтесь с основной сайт CodeAnalogies для 50+ учебников.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *