Recientemente he estado estudiando mucho sobre la funcionalidad y las formas de usar la biblioteca de JavaScript de Facebook React.js. Cuando se habla de sus diferencias con el resto del mundo de JavaScript, a menudo se mencionan los dos estilos de programación declarative
y imperative
.
¿Cuál es la diferencia entre ambos?
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.
Respuestas:
Un estilo declarativo, como el que tiene react, le permite controlar el flujo y el estado de su aplicación diciendo "Debería verse así". Un estilo imperativo le da la vuelta a eso y le permite controlar su aplicación diciendo "Esto es lo que debe hacer".
El beneficio de la declaración es que no se empantana en los detalles de implementación de la representación del estado. Está delegando el componente organizativo de mantener la coherencia de las vistas de su aplicación, por lo que solo tiene que preocuparse por el estado.
Imagina que tienes un mayordomo, que es una especie de metáfora de un marco. Y te gustaría hacer la cena. En un mundo imperativo, les dirías paso a paso cómo preparar la cena. Tienes que proporcionar estas instrucciones:
Go to the kitchen Open fridge Remove chicken from fridge ... Bring food to the table
En un mundo declarativo, simplemente describiría lo que quiere
I want dinner with chicken.
Si su mayordomo no sabe cómo hacer pollo, entonces no puede operar en un estilo declarativo. Al igual que si Backbone no sabe cómo mutarse para realizar una determinada tarea, no puede simplemente decirle que haga esa tarea. React puede ser declarativo porque "sabe hacer pollo", por ejemplo. En comparación con Backbone, que solo sabe interactuar con la cocina.
Ser capaz de describir el estado reduce drásticamente la superficie de los insectos, lo cual es un beneficio. Por otro lado, es posible que tenga menos flexibilidad en cómo ocurren las cosas porque está delegando o abstrayendo cómo implementa el estado.
fuente
Imagine un componente de interfaz de usuario simple, como un botón "Me gusta". Cuando lo toca, se vuelve azul si anteriormente era gris y gris si antes era azul.
La forma imperativa de hacer esto sería:
if( user.likes() ) { if( hasBlue() ) { removeBlue(); addGrey(); } else { removeGrey(); addBlue(); } }
Básicamente, debe verificar lo que está actualmente en la pantalla y manejar todos los cambios necesarios para volver a dibujarlo con el estado actual, incluido deshacer los cambios del estado anterior. Puede imaginar lo complejo que podría ser esto en un escenario del mundo real.
En contraste, el enfoque declarativo sería:
if( this.state.liked ) { return <blueLike />; } else { return <greyLike />; }
Debido a que el enfoque declarativo separa las preocupaciones, esta parte solo necesita manejar cómo debería verse la interfaz de usuario en un estado específico y, por lo tanto, es mucho más simple de entender.
fuente
Esta es una gran analogía:
* Una respuesta imperativa : Salga por la salida norte del estacionamiento y gire a la izquierda. Tome la I-15 sur hasta llegar a la salida de la autopista Bangerter. Gire a la derecha en la salida como si fuera a Ikea. Siga recto y gire a la derecha en el primer semáforo. Continúe hasta el siguiente semáforo y luego gire a la izquierda. Mi casa es el número 298.
Una respuesta declarativa : Mi dirección es 298 West Immutable Alley, Draper Utah 84020 *
https://tylermcginnis.com/imperative-vs-declarative-programming/
fuente
Es mejor comparar React (declarativo) y JQuery (imperativo) para mostrarle las diferencias.
En React, solo necesita describir el estado final de su IU en el
render()
método, sin preocuparse por cómo pasar del estado de IU anterior al nuevo estado de IU. P.ej,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> ) }
Por otro lado, JQuery requiere que realice la transición de su estado de interfaz de usuario de manera imperativa, por ejemplo, seleccionando los elementos de la etiqueta y actualizando su texto y 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); ... }
En el escenario del mundo real, habrá muchos más elementos de la interfaz de usuario para actualizar, además de sus atributos (por ejemplo, estilos CSS y detectores de eventos), etc. Si hace esto imperativamente usando JQuery, se volverá complejo y tedioso; es fácil olvidarse de actualizar algunas partes de la interfaz de usuario u olvidarse de eliminar los controladores de eventos antiguos (provocar pérdidas de memoria o disparos del controlador varias veces), etc. Aquí es donde ocurren los errores, es decir, el estado de la interfaz de usuario y el estado del modelo están fuera de sincronizar.
Los estados no sincronizados nunca sucederán con el enfoque declarativo de React, porque solo necesitamos actualizar el estado del modelo, y React es responsable de mantener la interfaz de usuario y los estados del modelo sincronizados.
También puede leer mi respuesta para ¿Cuál es la diferencia entre programación declarativa e imperativa? .
PD: del ejemplo anterior de jQuery, puede pensar qué pasaría si colocamos todas las manipulaciones DOM en un
updateAll()
método y lo llamamos cada vez que cambia alguno de los estados de nuestro modelo, y la interfaz de usuario nunca estará desincronizada. Tiene razón, y esto es efectivamente lo que hace React, la única diferencia es que jQueryupdateAll()
causará muchas manipulaciones DOM innecesarias, pero React solo actualizará los elementos DOM cambiados usando su Algoritmo de diferenciación DOM virtual .fuente
El código imperativo instruye a JavaScript sobre cómo debe realizar cada paso. Con código declarativo, le decimos a JavaScript lo que queremos hacer y dejamos que JavaScript se encargue de realizar los pasos.
React es declarativo porque escribimos el código que queremos y React está a cargo de tomar nuestro código declarado y realizar todos los pasos de JavaScript / DOM para llegar al resultado deseado.
fuente
Un paralelo de la vida real en el mundo imperativo sería entrar en un bar por una cerveza y darle las siguientes instrucciones al barman:
--Toma un vaso del estante
--Ponga el vaso delante del calado
- Tire del mango hacia abajo hasta que el vaso esté lleno
--Pásame el vaso.
En el mundo declarativo, en cambio, simplemente diría: "Cerveza, por favor".
El enfoque declarativo de pedir una cerveza asume que el bartender sabe cómo servir una, y ese es un aspecto importante del funcionamiento de la programación declarativa.
En la programación declarativa, los desarrolladores solo describen lo que quieren lograr y no es necesario enumerar todos los pasos para que funcione.
El hecho de que React ofrece un enfoque declarativo lo hace fácil de usar y, en consecuencia, el código resultante es simple, lo que a menudo conduce a menos errores y más facilidad de mantenimiento.
Dado que React sigue un paradigma declarativo, y no es necesario decirle cómo interactuar con el DOM; simplemente DECLARA lo que quiere ver en la pantalla y React hace el trabajo por usted.
fuente
La programación declarativa es un paradigma de programación ... que expresa la lógica de un cálculo sin describir su flujo de control.
La programación imperativa es un paradigma de programación que utiliza declaraciones que cambian el estado de un programa.
enlace de referencia: - https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2
fuente
Comenzaré con una analogía: tengo dos autos, en mis dos autos quiero que la temperatura dentro de mi auto sea la temperatura ambiente normal ~ 72 ° F. En el primer automóvil (más antiguo), hay dos perillas para controlar la temperatura (1 perilla para controlar la temperatura y 1 perilla para controlar el flujo de aire). Cuando hace demasiado calor, tengo que ajustar la primera perilla para bajar la temperatura y tal vez cambiar el flujo de aire) y viceversa si hace demasiado frío. ¡Este es un trabajo imperativo! Tengo que manejar las perillas yo mismo. En mi segundo automóvil (más nuevo), puedo establecer / declarar la temperatura. Lo que significa que no tengo que manipular las perillas para ajustar la temperatura que mi automóvil sabe, la declaro / configuro a 72 ° F y mi automóvil hará el trabajo imperativo para llegar a ese estado.
React es lo mismo, declaras el marcado / plantilla y la estadística, luego React hace el trabajo imperativo para mantener el DOM sincronizado con tu aplicación.
<button onClick={activateTeleporter}>Activate Teleporter</button>
En lugar de usar
.addEventListener()
para configurar el manejo de eventos, declaramos lo que queremos. Cuando se hace clic en el botón, ejecutará laactivateTeleporter
función.fuente
fuente