Syntaktisk sukker og JavaScript-diabetes

Syntaktisk sukker er stenografi for at kommunikere en større tanke på et programmeringssprog.

Jeg kan godt lide at sammenligne det med akronymer på naturlige sprog. Først kan det være forvirrende at se et nyt akronym, men når du først ved hvad det betyder, er det meget hurtigere!

Med syntaktisk sukker - som med akronymer - kan du GTFAMLH! (gå for langt og gøre livet sværere)

Jeg var frisk ude af college og lavede sjove apps på hackathons med mine venner og på en nybegynder JavaScript-spændende tur. Jeg følte mig ustoppelig . Jeg forstod alle eksemplerne på Codecademy, jeg forpligtede alle spørgsmål til frontendinterview til hukommelse. Jeg så "What the… JavaScript?" så mange gange, at hvis en voldsom abe skrammede tilfældige kodelinjer i en konsol, vidste jeg, hvad den ville evaluere.

Det var tid for mig at komme på GitHub og dele min gave med verden . Jeg åbnede det første projekt, jeg kunne finde, og begyndte at læse. Det så ud som dette:

function init(userConfig) { const DEFAULT_CONFIG = { removeSpaces: false, allowHighlighting: true, priority: "high", } const config = { ...DEFAULT_CONFIG, ...userConfig }; }

Øjeblikke senere ...

Forvirret og besejret lukkede jeg browserfanen og holdt op med dagen. Dette ville begynde en kæde af mig, der gjorde følgende:

  1. Oplev en kodelinje, som på det tidspunkt kun var JavaScript-hieroglyffer.
  2. Ikke at vide, hvordan man stiller de rigtige spørgsmål og udforme muligvis de værste Google-søgninger, mennesket har kendt.
  3. Plager tilfældige udviklere, indtil nogen kunne ”Forklare, at jeg er 5”, men i sidste ende stadig forvirret, hvorfor nogen ville skrive noget lignende. Sadisme, sandsynligvis .

4. At få det til at klikke, få hvorfor det er nyttigt, forstå hvilket problem det løser og forstå hvad folk gjorde tidligere for at løse problemet. Det var bare en mere kortfattet måde at skrive kode på! Det er bare sukker!

5. Undertiden ved at bruge det mådefor meget og gør min kode subjektivt værre.

6. At finde balancen og tilføje et fantastisk værktøj til min JavaScript-værktøjssæt. ?

5. Skyl og gentag ca. 20 gange.

Nu er jeg her for at prøve at nedbryde det bare for dig! For hvert sukkerholdigt trick vil jeg medtage nogle baggrundshistorier, et problem, det kan hjælpe med at løse, hvordan du kan opnå det før det syntaktiske sukker og situationer, hvor du måske ikke vil bruge det! ?

Ternær operatør

Den ternære operatør er en af ​​mine foretrukne til at starte med, når jeg taler om sukker i JavaScript, da det virkelig er let at gå for langt. Det tager normalt form af x ? a : b. Her er et mere realistisk eksempel:

const amILazy = true; const dinnerForTonight = amILazy ? "spaghetti" : "chicken";

Problem: Jeg har en variabel, der afhænger af, at en eller anden tilstand er sand eller falsk.

Kostløsning: Dette er dybest set bare en virkelig stenografisk måde at lave en if/else!

const amILazy = true; let dinnerForTonight = null; if(amILazy) { dinnerForTonight = "spaghetti"; } else { dinnerForTonight = "chicken"; }

Hvornår skal man ikke bruge det: Ternaries er en meget enkel måde at udtrykke forgrenede stier på. Efter min subjektive mening er det værste ved dem, at de er uendeligt rede. Så hvis du er en fan af jobsikkerhed, kan du muligvis skrive denne hjernesmelter.

const canYouFireMe = someCondition1 ? (someCondition2 ? false : true) : false

Klassisk eksempel på JavaScript-diabetes. Mindre kode betyder ikke mere kortfattet kode.

Objekt spredning

Åh, eksemplet fra starten, der knuste mit hjerte. I Javascript, når du ser ..., afhængigt af kontekst det vil være Objekt / Array Spread, eller Objekt / Array Rest. Vi skal dække hvile lidt, så lad os lægge det på bagbrænderen.

Spredning er grundlæggende at tage et enkelt objekt, trække alle dets nøgle / værdipar ud og lægge dem i et andet objekt. Her er et grundlæggende eksempel på spredning af to objekter i et nyt objekt:

const DEFAULT_CONFIG = { preserveWhitespace: true, noBreaks: false, foo: "bar", }; const USER_CONFIG = { noBreaks: true, } const config = { ...DEFAULT_CONFIG, ...USER_CONFIG }; // console.log(config) => { // preserveWhitespace: true, // noBreaks: true, // foo: "bar", // }

Problem: Jeg har et objekt, og jeg vil lave et andet objekt, der har de samme nøgler med alle de samme værdier. Måske vil jeg gøre det med flere objekter, og hvis der er duplikatnøgler, skal du vælge hvilket objekts nøgler vinder ud.

Kostløsning: Du kan bruge Object.assign()til at opnå en lignende effekt. Det tager et hvilket som helst antal objekter som argumenter, prioriterer de mest objekter, når det kommer til nøgler, og ender med at mutere det allerførste objekt, der er givet. En almindelig fejl er ikke at passere et tomt objekt som det første argument og ved et uheld at muteere et argument, som du ikke mente.

Hvis det er svært at følge, vil du være glad for at vide, at Object Spread gør det umuligt. Her er et eksempel, der replikerer den syntaktiske sukkerversion.

const DEFAULT_CONFIG = { preserveWhitespace: true, noBreaks: false, foo: "bar", }; const USER_CONFIG = { noBreaks: true, } // if we didn't pass in an empty object here, config // would point to DEFAULT_CONFIG, and default config would be // mutated const config = Object.assign({}, DEFAULT_CONFIG, USER_CONFIG);

Objekt spredning fjerner chancen for en utilsigtet mutation. Så du kunne gøre ting, som at opdatere Redux State uden frygt for ved et uheld at holde en reference, der får en lav sammenligning til at fejle.

? Bonus ? Ar ray spread fungerer meget ens! Men da der ikke er nogen nøgler i arrays, tilføjer det bare slags det til det nye array som et Array.Prototype.concatopkald.

const arr1 = ['a', 'b', 'c']; const arr2 = ['c', 'd', 'e']; const arr3 = [...arr1, ...arr2]; // console.log(arr3) => ['a', 'b', 'c', 'c', 'd', 'e']

Objektdestrukturering

Denne ser jeg ret almindeligt ude i naturen. Nu har vi vores nye konfigurationsobjekt fra det foregående eksempel og vil bruge det i vores kode. Du kan muligvis se noget som dette spredt om kodebasen.

const { preserveWhiteSpace, noBreaks } = config; // Now we have two new variables to play around with! if (preservedWhitespace && noBreaks) { doSomething(); };

Problem: At skulle skrive hele stien til en nøgle i et objekt kan blive ret tung og tilstoppe meget af koden. For at være mere kortfattet ville det være bedre at lave en variabel ud af værdien for at holde koden pæn.

Kostløsning: Du kan altid gøre det på den gammeldags måde! Det ville se sådan ud.

const preserveWhitespace = config.preserveWhitepsace; const noBreaks = config.noBreaks; // Repeat forever until you have all the variables you need if (preservedWhitespace && noBreaks) { doSomething(); };

When not to use it: You can actually destructure an object out of an object, and continue to destructure deeper and deeper! Destructuring isn’t the only way to get a key out of an Object. If you find yourself only using destructuring for keys two or three layers deep, chances are you are doing more harm than good to the project.

? Bonus ? Arrays also have destructuring, but they work based off index.

const arr1 = ['a', 'b'] const [x, y] = arr1 // console.log(y) => 'b'

Object Rest

Object Rest goes hand in hand with Object Destructuring, and is very easy to confuse with Object Spread. Once again we use the ... operator, however the context is different. This time, it shows up while destructuring and is intended to gather leftover keys into one object. ?

const { preserveWhiteSpace, noBreaks, ...restOfKeys } = config; // restOfKeys, is an object containing all the keys from config // besides preserveWhiteSpace and noBreaks // console.log(restOfKeys) => { foo: "bar" }

Problem: You want an object that has a subset of keys from another object.

Diet Solution: You could use our old pal Object.assign and delete any of the keys that you don’t need! ?

When not to use it: Using it to create a new object with omitted keys is a common use case. Just be aware that the keys you are omitting in the destructure are still floating around and potentially taking up memory. If you’re not careful, this could cause a bug. ?

const restOfKeys = Object.assign({}, config); delete restOfKeys.preserveWhiteSpace delete restOfKeys.noBreaks

? Bonus ? Guess what? Arrays can do something similar and it works exactly the same!

const array = ['a', 'b', 'c', 'c', 'd', 'e']; const [x, y, ...z] = array; // console.log(z) = ['c', 'c', 'd', 'e']

Wrapping up

JavaScript-sukker er fantastisk, og forståelse af, hvordan man læser det, giver dig mulighed for at indtaste mere forskellige kodebaser og udvide dit sind som udvikler. Bare husk at det er en afbalanceret handling mellem at være kortfattet og gøre din kode læsbar for andre og dit fremtidige selv.

Selvom det måske føles fantastisk at vise dit skinnende nye værktøj, er vores job som programmører at lade kodebaser være mere vedligeholdelige, da de var, da vi kom ind i dem.

Her er en samling af MDN-dokumenterne om, hvad jeg dækkede, hvis du vil læse yderligere. ?

  • Ternær operatør
  • Spred syntaks
  • Destruktureringsopgave
  • Hvileparametre