Недавно я много изучал функциональность и способы использования JavaScript-библиотеки Facebook React.js. Говоря о его отличиях от остального мира JavaScript, часто упоминаются два стиля программирования declarative
и imperative
.
В чем разница между ними?
Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
Ответы:
Декларативный стиль, подобный тому, что имеет response, позволяет вам управлять потоком и состоянием в вашем приложении, говоря: «Это должно выглядеть так». Императивный стиль меняет ситуацию и позволяет вам управлять своим приложением, говоря: «Это то, что вы должны делать».
Преимущество декларативного подхода в том, что вы не увязнете в деталях реализации представления состояния. Вы делегируете организационный компонент согласованности представлений приложения, поэтому вам просто нужно беспокоиться о состоянии.
Представьте, что у вас есть дворецкий, который является своего рода метафорой каркаса. И вы хотите приготовить ужин. В императивном мире вы пошагово объясните им, как приготовить ужин. Вы должны предоставить следующие инструкции:
Go to the kitchen Open fridge Remove chicken from fridge ... Bring food to the table
В декларативном мире вы просто описываете то, что хотите
I want dinner with chicken.
Если ваш дворецкий не знает, как приготовить курицу, вы не можете действовать декларативно. Точно так же, как если Backbone не знает, как изменить себя для выполнения определенной задачи, вы не можете просто сказать ему, чтобы она выполняла эту задачу. React может быть декларативным, потому что, например, он «умеет делать курицу». По сравнению с Backbone, который умеет взаимодействовать только с кухней.
Возможность описать состояние значительно уменьшает площадь обнаружения ошибок, что является преимуществом. С другой стороны, у вас может быть меньше гибкости в том, как что-то происходит, потому что вы делегируете или абстрагируетесь от того, как вы реализуете состояние.
источник
Представьте себе простой компонент пользовательского интерфейса, например кнопку «Нравится». Когда вы нажимаете на него, он становится синим, если раньше был серым, и серым, если раньше был синим.
Обязательный способ сделать это:
if( user.likes() ) { if( hasBlue() ) { removeBlue(); addGrey(); } else { removeGrey(); addBlue(); } }
По сути, вы должны проверить, что в настоящее время находится на экране, и обработать все изменения, необходимые для его перерисовки с текущим состоянием, включая отмену изменений из предыдущего состояния. Вы можете себе представить, насколько сложно это могло быть в реальном сценарии.
Напротив, декларативный подход был бы следующим:
if( this.state.liked ) { return <blueLike />; } else { return <greyLike />; }
Поскольку декларативный подход разделяет проблемы, эта его часть должна обрабатывать только то, как пользовательский интерфейс должен выглядеть в определенном состоянии, и, следовательно, ее гораздо проще понять.
источник
Это отличная аналогия:
* Обязательный ответ : выйдите из северного выхода с парковки и поверните налево. Двигайтесь по автомагистрали I-15 на юг, пока не дойдете до съезда с шоссе Bangerter. Сверните направо с выхода, как будто вы собираетесь в Икеа. Идите прямо и на первом светофоре поверните направо. Продолжайте движение к следующему светофору, затем поверните налево. Мой дом № 298.
Декларативный ответ : Мой адрес: 298 West Immutable Alley, Draper Utah 84020 *.
https://tylermcginnis.com/imperative-vs-declarative-programming/
источник
Лучше всего сравнить React (декларативный) и JQuery (императивный), чтобы показать вам различия.
В React вам нужно только описать конечное состояние вашего пользовательского интерфейса в
render()
методе, не беспокоясь о том, как перейти из предыдущего состояния пользовательского интерфейса в новое состояние пользовательского интерфейса. Например,render() { const { price, volume } = this.state; const totalPrice = price * volume; return ( <div> <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... /> <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... /> <Label value={totalPrice} ... /> ... </div> ) }
С другой стороны, JQuery требует от вас обязательного перехода состояния пользовательского интерфейса, например, выбора элементов метки и обновления их текста и CSS:
updatePrice(price) { $("#price-label").val(price); $("#price-label").toggleClass('expansive', price > 100); $("#price-label").toggleClass('cheap', price < 100); // also remember to update UI depending on price updateTotalPrice(); ... } updateVolume(volume) { $("#volume-label").val(volume); $("#volume-label").toggleClass('high', volume > 1000); $("#volume-label").toggleClass('low', volume < 1000); // also remember to update UI depending on volume updateTotalPrice(); ... } updateTotalPrice() { const totalPrice = price * volume; $("#total-price-label").val(totalPrice); ... }
В реальном сценарии будет обновляться гораздо больше элементов пользовательского интерфейса, а также их атрибуты (например, стили CSS и прослушиватели событий) и т. Д. Если вы сделаете это в обязательном порядке с помощью JQuery, это станет сложным и утомительным; легко забыть обновить некоторые части пользовательского интерфейса или забыть удалить старые обработчики событий (вызвать утечку памяти или срабатывание обработчика несколько раз) и т. д. Именно здесь возникают ошибки, т. е. состояние пользовательского интерфейса и состояние модели выходят за рамки синхронизировать.
Состояния рассинхронизации никогда не произойдут с декларативным подходом React, потому что нам нужно только обновить состояние модели, а React отвечает за синхронизацию пользовательского интерфейса и состояний модели.
Вы также можете прочитать мой ответ на вопрос: В чем разница между декларативным и императивным программированием? .
PS: из приведенного выше примера jQuery вы можете подумать, что, если мы поместим все манипуляции с DOM в
updateAll()
метод и будем вызывать его каждый раз, когда любое из наших состояний модели изменяется, и пользовательский интерфейс никогда не будет рассинхронизирован. Вы правы, и это фактически то, что делает React, с той лишь разницей, что jQueryupdateAll()
вызовет множество ненужных манипуляций с DOM, но React будет обновлять только измененные элементы DOM, используя свой алгоритм Virtual DOM Diffing .источник
Императивный код указывает JavaScript, как он должен выполнять каждый шаг. С помощью декларативного кода мы сообщаем JavaScript, что мы хотим сделать, и позволяем JavaScript позаботиться о выполнении шагов.
React является декларативным, потому что мы пишем код, который нам нужен, а React отвечает за принятие нашего объявленного кода и выполнение всех шагов JavaScript / DOM для достижения желаемого результата.
источник
Реальная параллель в императивном мире - это войти в бар за пивом и дать следующие инструкции бармену:
- Возьмите стакан с полки
- Поставьте стекло перед сквозняком
- Опустите ручку вниз, пока стакан не наполнится
- Передай мне стакан.
Вместо этого в декларативном мире вы бы просто сказали: «Пиво, пожалуйста».
Декларативный подход к запросу пива предполагает, что бармен знает, как его подать, и это важный аспект работы декларативного программирования.
В декларативном программировании разработчики описывают только то, чего они хотят достичь, и нет необходимости перечислять все шаги, чтобы это работало.
Тот факт, что React предлагает декларативный подход, упрощает его использование, и, следовательно, результирующий код прост, что часто приводит к меньшему количеству ошибок и большей простоте обслуживания.
Поскольку React следует декларативной парадигме, и нет необходимости указывать ему, как взаимодействовать с DOM; вы просто ОБЪЯВЛЯЕТЕ, что вы хотите видеть на экране, и React сделает всю работу за вас.
источник
Декларативное программирование - это парадигма программирования ... которая выражает логику вычисления без описания его потока управления.
Императивное программирование - это парадигма программирования, в которой используются операторы, изменяющие состояние программы.
ссылка: - https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2
источник
Я начну с аналогии: у меня две машины, в двух моих машинах я хочу, чтобы температура в моей машине была нормальной комнатной, ~ 72 ° F. В первом (старом) автомобиле есть две ручки для управления температурой (1 ручка для управления температурой и 1 ручка для управления воздушным потоком). Когда становится слишком жарко, я должен отрегулировать первую ручку, чтобы снизить температуру и, возможно, изменить воздушный поток) и наоборот, если слишком холодно. Это обязательная работа! Я должен сам управлять ручками. В моей второй (более новой) машине я могу установить / объявить температуру. Это означает, что мне не нужно возиться с ручками, чтобы отрегулировать температуру, которую моя машина знает, я объявляю / устанавливаю ее на 72 ° F, и моя машина сделает всю необходимую работу, чтобы добраться до этого состояния.
React такой же, вы объявляете разметку / шаблон и stat, а затем React выполняет обязательную работу, чтобы поддерживать DOM в синхронизации с вашим приложением.
<button onClick={activateTeleporter}>Activate Teleporter</button>
Вместо того,
.addEventListener()
чтобы использовать для настройки обработки событий, мы объявляем то, что хотим. Когда кнопка нажата, она запускаетactivateTeleporter
функцию.источник
источник