Синтактична захар и JavaScript диабет

Синтактичната захар е стенография за предаване на по-голяма мисъл на език за програмиране.

Обичам да го сравнявам със съкращения на естествени езици. Отначало виждането на нова абревиатура може да ви обърка, но след като разберете какво означава това е по-бързо!

Със синтактична захар - като със съкращения - можете да GTFAMLH! (отидете твърде далеч и затруднявайте живота)

Бях наскоро в колежа, правех забавни приложения на хакатони с моите приятели и в начинаеща разходка с JavaScript. Чувствах се неудържим . Разбрах всички примери на Codecademy, записах всеки въпрос за интервю от предния край на памет. Гледах „Какво ... JavaScript?“ толкова много пъти, че ако пищяща маймуна извика, забие случайни редове код в конзола, знаех какво ще оцени.

Време беше да се кача на GitHub и да споделя подаръка си със света . Отворих първия проект, който намерих, и започнах да чета. Изглеждаше по следния начин:

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

Моменти по-късно ...

Объркан и победен, затворих раздела на браузъра и напуснах деня. Това ще започне верига от мен, като правя следното:

  1. Открийте ред от код, който по това време е бил само йероглифи на JavaScript.
  2. Не знаейки как да задавате правилните въпроси и да създадете съвсем вероятно най-лошите търсения в Google, познати на човечеството.
  3. Досадите на произволни разработчици, докато някой не може да „обясни, че съм на 5“, но в крайна сметка все още сме объркани защо някой ще напише нещо подобно. Садизъм, вероятно .

4. Щракнете върху него, разберете защо е полезно, разберете какъв проблем решава и разберете какво са правили хората в миналото, за да разрешат проблема. Това беше просто по-кратък начин за писане на код! Това е просто захар!

5. Понякога, използвайки го по начинтвърде много и влошаване на кода ми субективно.

6. Намиране на баланса и добавяне на чудесен инструмент към моя инструментариум за JavaScript. ?

5. Изплакнете и повторете около 20 пъти.

Сега съм тук, за да се опитам да го разбия просто за вас! За всеки сладък трик ще включа предистория, проблем, който би могъл да помогне, как да го постигнете преди синтактичната захар и ситуации, в които може да не искате да го използвате! ?

Троичен оператор

Ternary Operator е един от любимите ми, с които трябва да започна, когато говорим за захар в JavaScript, тъй като е много лесно да се стигне твърде далеч. Обикновено приема формата на x ? a : b. Ето по-реалистичен пример:

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

Проблем: Имам променлива, която зависи от това дали дадено условие е вярно или невярно.

Диетично решение: Това всъщност е просто наистина стенографичен начин да се направи if/else!

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

Кога да не го използвате: Тернарите са много прост начин за изразяване на разклонени пътеки. Според моето субективно мнение най-лошото при тях е, че са безкрайно изчезващи. Така че, ако сте фен на сигурността на работното място, потенциално бихте могли да напишете този разтопител на мозъка.

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

Класически пример за JavaScript диабет. По-малко код не означава по-кратък код.

Разпространение на обекта

А, примерът от самото начало, който ми разби сърцето. В Javascript, когато видите ..., в зависимост от контекста ще бъде Object / Array Spread или Object / Array Rest. Ще покрием малко почивка, така че нека я сложим на задната горелка.

Разпространението е основно вземане на един обект, изваждане на всички негови двойки ключ / стойност и поставянето им в друг обект. Ето един основен пример за разпространение на два обекта в нов обект:

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", // }

Проблем: Имам обект и искам да направя друг обект, който има едни и същи ключове, с едни и същи стойности. Може би искам да направя това с множество обекти и ако има дублирани ключове, изберете ключовете на кой обект да спечелят.

Диетично решение: Можете да използвате, за Object.assign()да постигнете подобен ефект. Той взема произволен брой обекти като аргументи, дава приоритет на най-десните обекти, що се отнася до ключовете, и в крайна сметка мутира първия даден обект. Често срещана грешка е да не се предаде празен обект като първи аргумент и случайно да се мутира аргумент, който не сте искали.

Ако това е трудно да се следва, ще се радвате да разберете, че Object Spread прави това невъзможно. Ето пример, който възпроизвежда версията на синтактичната захар.

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

Разпространението на обекти премахва шанса за случайна мутация. Така че можете да правите неща, като например да актуализирате Redux State, без страх от случайно запазване на препратка, причинявайки неуспех на плиткото сравнение.

? Бонус? Ar ray spread работи много подобно! Но тъй като в масивите няма никакви ключове, той просто го добавя към новия масив като Array.Prototype.concatповикване.

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

Деструктуриране на обекти

Този го виждам доста често в природата. Сега имаме нашия нов обект за конфигуриране от предишния пример и искаме да го използваме в нашия код. Може да видите нещо подобно разпръснато за кодовата база.

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

Проблем: Трябва да изписвате целия път до ключ в обект, може да стане доста тежък и да задръсти голяма част от кода. За да бъдем по-кратки, би било по-добре да направим променлива от стойността, за да поддържаме кода чист.

Диетично решение: Винаги можете да го направите по старомоден начин! Това би изглеждало така.

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 sugar is great, and understanding how to read it will allow you to enter more diverse code bases and expand your mind as a developer. Just remember that it’s a balancing act between actually being concise, and making your code readable for others and your future self.

While it might feel awesome showing off your shiny new tool, our job as programmers is to leave codebases more maintainable then they were when we entered them.

Here’s a collection of the MDN Documents on what I covered if you want to do some further reading. ?

  • Ternary Operator
  • Spread Syntax
  • Destructuring Assignment
  • Rest Parameters