Angiv i JavaScript forklaret ved at tilberede et simpelt måltid

Hvis du nogensinde har tilberedt et måltid derhjemme, kan du forstå, hvordan man skriver stateful kode ved hjælp af objektorienterede programmeringsmetoder i JavaScript.

Når du begynder at skrive enkle JavaScript-programmer, behøver du ikke bekymre dig om antallet af variabler, du bruger, eller hvordan forskellige funktioner og objekter fungerer sammen.

For eksempel starter de fleste med at bruge mange globale variabler eller variabler, der er scopet på filens øverste niveau. De er ikke en del af en individuel klasse, objekt eller funktion.

For eksempel er dette en global variabel kaldet tilstand :

let state = "global";

Men når dit program begynder at involvere mange forskellige funktioner og / eller objekter, skal du oprette et strengere regelsæt for din kode.

Det er her, begrebet stat spiller ind. Tilstand beskriver status for hele programmet eller et individuelt objekt. Det kan være tekst, et tal, en boolsk eller en anden datatype.

Det er et almindeligt værktøj til koordinering af kode. For eksempel, når du opdaterer tilstanden, kan en masse forskellige funktioner øjeblikkeligt reagere på den ændring.

Denne artikel beskriver tilstand i sammenhæng med React, et populært JavaScript-bibliotek.

Men gæt hvad? Selv tilstand kan give dig hovedpine, når din kode bliver kompliceret! Ændring af tilstand kan medføre utilsigtede konsekvenser.

Lad os stoppe lige der. Stat er et populært værktøj inden for objektorienteret programmering eller OOP. Men mange programmører foretrækker funktionel programmering, hvilket afskrækker tilstandsændringer. JavaScript understøtter begge paradigmer.

Okay, det er en masse terminologi på én gang. Jeg ønskede at finde en måde at vise, hvordan OOP og funktionel programmering kan nå de samme mål, selvom funktionel programmering ikke bruger tilstand.

Denne vejledning viser, hvordan du kan tilberede et måltid med spaghetti og sauce fra en OOP og et funktionelt perspektiv.

Her er en hurtig forhåndsvisning af de to forskellige tilgange:

Lad os hoppe ind i det. For at forstå denne vejledning skal du bare forstå funktioner og objekter i JavaScript.

Objektorienteret metode (ved hjælp af tilstand)

I grafikken ovenfor viste vi to forskellige tilgange til at lave denne pastamiddag:

  1. En metode, der er fokuseret på de forskellige værktøjers tilstand, som komfur, gryde og pasta.
  2. En metode, der er fokuseret på progressionen af ​​selve maden uden at nævne tilstanden for de enkelte værktøjer (gryder, komfurer osv.)

Den objektorienterede tilgang fokuserer på opdatering af tilstand, så vores kode vil have tilstand på to forskellige niveauer:

  1. Global eller tilstanden af ​​hele dette måltid.
  2. Lokalt for hvert objekt.

Vi skal bruge ES6-syntaks i denne vejledning til at oprette objekter. Her er et eksempel på den globale stat og prototypen "Pot".

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);// Pot { boilStatus = 'boiling'; }

Bemærk: Jeg forenklede console.logudsagnet for at fokusere på statusopdateringen.

Her er en visuel gengivelse af denne logik:

Før

Efter

Der er to tilstande, og når den pastaPotoprettes via Potprototypen, har den oprindeligt en tom boilStatus. Men så er der en statsændring.

Vi løber pastaPot.startBoiling(), og nu boilStatuskoger den (lokale stat), da den globale tilstand stoveTemper over 400.

Now let’s go one step further. We will allow the pasta to become boiled due to the state of pastaPot.

Here’s the code we will add to the snippet above:

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);// true

Woah! That’s a lot at once. Here’s what happened.

  1. We created a new prototype of “Pasta”, where every object will have a local state called cookedStatus
  2. We created a new instance of Pasta called myMeal
  3. We used the state from the pastaPot object that we created in the last snippet to determine if we should update the state called cookedStatus in myMeal to cooked.
  4. Since the state of boilStatus in pastaPot was “boiling”, our pasta is now cooked!

Here’s that process visually:

Before

After

So, we now have the local state of one object, that depends on the local state of another object. And that local state depended on some global state! You can see how this can be challenging. But, it is at least easy to follow for now, since states are updated explicitly.

Functional Method (without state)

In order to fully understand state, you should be able to find a way to accomplish the same outcome as the code above without actually modifying state. This is where functional programming helps!

Functional programming has two core values that separate it from OOP: immutability and pure functions.

I am not going to go into too much depth on those topics, but if you want to learn more, I encourage you to check out this guide to functional programming in JavaScript.

Both of these principles discourage the use of state modification in your code. That means that we can’t use local or global state.

Functional programming instead encourages us to pass in parameters to individual functions. We can use outside variables, but we can’t use them as state.

Here’s an example of a function that will boil the pasta:

const stoveTemp = 500;
const cookPasta = (temp) => { if(temp > 400) return 'cooked';}
console.log(cookPasta(stoveTemp));// 'cooked'

This code will successfully return a string of ‘cooked’. But notice — there is no object that we are updating. The function simply returns the value that will be used in the next step.

Instead, we are focused on the inputs and outputs of one function: cookPasta.

This perspective looks at the transformation of the food itself, rather than the tools that are used to cook it. It’s a little harder to visualize, but we don’t need to have the function depend on external state.

Here’s what it looks like:

Tænk på det som en "tidslinjevisning" for måltidets fremskridt - denne særlige funktion dækker bare den første del, overgangen fra tør pasta til kogt pasta.

Lad os nu dække den anden del, mens maden serveres. Her er koden, der serverer måltidet. Det kommer efter kodeblokken ovenfor:

const serveMeal = (pasta) => { if (pasta == 'cooked') return 'Dinner is ready.'}
console.log( serveMeal(cookPasta(stoveTemp)) );// 'Dinner is ready.'

Nu leverer vi resultaterne af cookPastafunktionen direkte til serveMealfunktionen. Igen er vi i stand til at gøre dette uden at ændre tilstand eller ændre datastrukturer.

Her er et diagram, der bruger "tidslinjevisningen" til at vise, hvordan disse to funktioner fungerer sammen:

Interesseret i flere visuelle vejledninger?

Hvis du nød denne guide, skal du give den en "klapp"!

Og hvis du gerne vil læse flere visuelle tutorials om HTML, CSS og JavaScript, skal du tjekke det vigtigste CodeAnalogies-websted for mere end 50 tutorials.