Рэальная складнасць сучаснага JavaScript вырабляецца за дапамою інструментаў, а не самай мовы.
У этай статыце пояснюецца, як такі ключовыя функцыі JavaScript, як async/await і optional chaining, спрыяюць спрасцоўванню коду, тады калі занадта многа інструментаў і залежнасцей ствараюць непатрэбную складнасць.
У развітку JavaScript існуе дзіўны момент, калі вы усвядомляеце, што знаеце занадта многа.
Не сам JavaScript у великай кількасці.
Занадта многа інфармацыі пра экосистему, яка абрамляе JavaScript.
Вы опанавалі React. Потым з’явіліся хукі. Далей у гру вступала адарботка з станамі, пасля чаго з’явілася ваша улюбленая бібліятэка для адарботки зі станамі. У вас сформаваліся чысткія падзіркі ўжо ў аспекте запрашэння дадзеных на кліенте. Вы розумееце, што робіць бандлер, хоця рэдкаа чытаеце його канфігурацыйны файл. Вы сталкнуліся з серверскімі компонентамі, сігналамі, айлендамі, рантаймамі на краю сеті, мета-фреймворкамі, інструментамі для будування проектаў, лінтарамі, форматарамі, менеджерамі пакетаў, а таксама не менш чым тромя конкуруючымі стандартамі для арганізацыі папкі пад назвай components.
Потым вы ачынаеце маленькі файл JavaScript і усвядомляеце, што справжняя логіка сводзіцца да гэтага:
const users = await fetch("/api/users").then(res => res.json());
Гэта і ўсё.
Сама мова частаца дзійсна простая, як можна было б спадзецца.
Тое, што робіць савэчасны JavaScript такім складным, — гэта всё тое, што дадаўся на яго аднойчы.
Калі колькасць файлаў з кодам на JavaScript зрастае з калькі з неколькох да систем, якія маюць сотні залежнасцей, гэта свідчыць пра тое, што мы плутамо высокую ступеню развіцця з аднаковаю складнасцю.
Работа з савэчасным JavaScript не значыць неабходнасць вжывання кожнай новай функцыі, яку ён праследжвае.
Гэта значыць павінны быць зрозумелыя тые проблэмы, якія мова вже рашыла за вас.
Мова тыхо вырасла
JavaScript калі-то меў репутацыю дзівнае, спяшна разрабатанай мовы, якая якимсь чынам стала аднойчы основай усіх веб-сайтаў.
Частка гэтай репутацыі была справядлівая.
У першыя версіі існаваў справжній тарган. API прыстроёў прыведчэння не працавалі адносова стабільна ў розных сэрварных сераўніках. Разумець асінхронны код было практычна немагчыма. У часе выканання не было вбудованных модуляў, таму большыя кодавыя базы вынужданы былі паслявацца на шаблоны, якія часта выглядалі болей складнымі, чым сам язык.
Сучасны JavaScript — цэлакашна іншая історыя.
Ось калікі можласцяў у вас зараз ёсць:
- Зменныя з блаковым дыапазонам выкарыстоўвання через
constіlet - Корткая сінтаксіс функцый за дапамогою стрэлавых функцый
- Деструктурыраванне для выкарыстоўвання значэнняў з об’ектаў і масоў
- Інтерполяцыя страк з викорыстанням шаблонавых літэралаў
- Стандартныя параметры, якія дазволяюць ухіліцца ад ручных пераглядаў на альтернатывы
- Сінтаксіс распрасцэрання для копіювання і з’еднання дадзеных
- Натыўная система модуляў
- Класы, якія выкарыстоўваюцца толькі тады, калі цэлкам неабходна
async і awaitMap і SetЖадная з эйталонных функцый не робіць мову складнойю для выкарыстоўвання.
Асалідныя проблемы заключаюцца у тым, што разработчыкі часта запам’ятовуюць гэтыя синтаксыс як вельмі складную структуру, замест таго каб спрыяць іх викорыстоўванню як компактны набор засобаў для выражэння будзь-якіх практычных програмістскіх ідэй.
Калі основныя ідеі стануць зрозумелымі, синтаксыс перестае выдавацца страшным.
Вам, верагодна, не патрэбна половіна архітектуры
Аднам з найшырэйшых спосабоў перакомплікаваць проект на JavaScript ёст тое, што прыміць рашэнняя па архітектуры ўжо да таго часу, калі яшчэ не зрозумелі саму проблему.
Уявіце панель керавання: яна должна завантажыць дакументацыю, дазволіць корыстніку яе зменіць і запісаць рэзультат.
Разумны першы падход можа выглядаць так:
async function loadUsers() {
const response = await fetch("/api/users");
if (!response.ok) {
throw new Error("Failed to load users");
} return response.json();
}
Потым вызванне яго ёст проста:
const users = await loadUsers();
На адной такой модэлі можна стварыць значны час тэхнічных рашэнняў.
Аднак сучасныя звычкі праганяюць нас негайна задаць множыну пытанняў замест таго:
Чы гэтакі фреймворк трэба выбраць адразу?
А як ўзглянуць на слой для запошчання дадзеных?
Чы патрэбна спецыяльная бібліятэка толькі для керавання станам?
Чы трэба маты механізм кэшавання пры запитах?
Чы неабходна бібліятэка для верыфікацыі схемы?
Як трэба арганізаваць папкі і файлы?
Какія шаблоны павінны следаваць вашым компанентам?
Какі інструмент для зборкі павінен асамаваць усё?
Які падход павінен выкарыстоўваць сервер для обробкі запитаў?
Гэтыя пытанні можу стаць важлівымі з часам.
Рэдкая раз яны ёсць правымі пытаннямі для пачатку.
Першае пытанне завжды павінна быць:
Што на самай працоўкі патрабуе гэтае застосунак?
Гэтыя разлікі важны, таму што кожная абстракцыя мае свой цэнавак.
Кожны з гэтых элементаў дагадвае новую ідэю, якую хтось іншы павінен выучыць, прычаму толькі тады ён зможа безпечна працаваць з кодам.
Якщо звычная функцыя можа выпаліць задачу, верагатэчна вам не патрэбны класы.
Якщо модуль можа выпаліць задачу, верагатэчна вам не патрэбны фреймворкі.
Якщо звычны об’ект можа хаваць ваш стан, верагатэчна вам не патрэбная система керування станом.
Якщо fetch() падходзіць для вашых задач, яшчэ адны слой для запрашання дадзеных можа стаць толькі дапаможнай перакладкай межы між вамі і сетчукаў.
Нічга з гэтага не значыць, што фреймворкі за сваёю сутнасцю ўжо паслабленыя рашэння.
Это значыць, што фреймворк павінен рашаць адную з вашых рэальных проблем, а не тую, якую вы самі сабе уявілі.
async і await скасавалі вялічыню псыхічнага навантажэння
Не кожны значны апдэйт у сучаснам JavaScript є выразным.
async і await — гэта чырвоны прыклад тыхя, але значнага павышэння якасці коду.
Паглядзім на стары падход, базаваны на калебэках:
getUser(id, function (user) {
getOrders(user, function (orders) {
processOrders(orders, function (result) {
console.log(result);
});
});
});
Проблема была не толькі ў тым, што такі код візуальна выглядаў некрасіва.
Глыбока іерархія калебэкаў справачыналі вельмі складным адстэпленнем па ходу выканання.
Promises падбілі ситуацыю:
getUser(id)
.then(user => getOrders(user))
.then(orders => processOrders(orders))
.then(result => console.log(result));
А потым async і await прыблізілі асінхронны код да звычайной, секвэнцыйнае выглядаючай логікі:
const user = await getUser(id);
const orders = await getOrders(user);
const result = await processOrders(orders);
console.log(result);
Такія функцыяналы зазвычай стаюць непазначальнымі, калі яны стануць звычкай.
Это на самай працоўны знак хорашага дзяйнаўдзення.
Хораша падготавленыя функцыяналы языка зазвычай зникаюць у звычайным вжыванні, а не прывлекаюць увагу.
Памылка заключаецца ў тым, што люди вырашаюць, iхта ўжо асінхронная праця за сваймі законамі є складной, то синтаксіс, які яе огранічвае, таксама павінен быць складным.
У большасці случаў так не ёсць.
Распакоўванне — гэта не тест на характер
Дзеякі разработчы так сильна паслужваюцца распакоўваннем, што звычны код стае важкім для аналізу.
Паглядзіце на гэта:
const { name, email, address: { city } } = user;
У гэтага є свое месца.
Але іншыя разы тут все чытальней:
const name = user.name;
const email = user.email;
const city = user.address.city;
Немае додатковых балоў за тое, што ў одну лінію запхаць як магчыма больш синтаксісу.
Распакоўванне мае сэнс тады, калі яно робіць звязак межа кодам і базовымі дадзенням болей ясным.
Напрыклад:
function createUser({ name, email }) {
// ...
}
Гэта выразна.
Це точна паведамляе чытальніку, якога формата об’екта чакае функцыя.
Але калі распакоўка стае настолькі глęбокай, што чытачу патрабуецца ментальна перабудаваць первісную структуру об’екта, гэта якосты прыпыняе дапамагаць і начынае паводзіцца проты вас.
Сучасны JavaScript застаецца простым, калі синтаксі спрыяе комунікацыі, а не ўжо толькі декору.
Необавязковая ланцюгова перамысловасць рашыла рэальную проблему
Дзеяныя якосты даслівна зменшаюць колькасць непатрэбных элементаў.
Необавязковая ланцюгова перамысловасць — гарны прыклад.
Да ўведэння яе часта можна было пабачыць ў такім варыянті:
if (
user &&
user.profile &&
user.profile.settings &&
user.profile.settings.theme
) {
return user.profile.settings.theme;
}
Тепер можна запісаць:
return user?.profile?.settings?.theme;
Гэта не толькі корачэ.
Гэта прымусова выказвае намер.
Разработчык фактычна кажа:
Гэтый шлях можа не існаваць. Якщо ён нямае, безпечна выйсці з ціўкі.
Тая ж логіка прыменшуецца і да функцыі з’еднання значэнняў, калі яны є null:
const pageSize = options.pageSize ?? 20;
якая часта є болей тачной, чым:
const pageSize = options.pageSize || 20;
Таму што || спрыяе тым, што ложныя значэнняяк 0 чы роўна "" спрацьвоваюць так, як бы іх не было, тады калі ?? реагуе толькі на null чы undefined.
Такія функцыі ўартуюць выучэння, таму што яны усуняюць ненавоколлічную складнасць, а не дадаюць дапамогі у стварэнні красавічнага стылю коду.
Ось корыстны фільтр, які можна застосавіць да будзь-яй новай сынтаксі:
Чы гэта робіць код простейшым для разумення?
Якщо адказ «так», выучыце гэта.
Якщо гэта толькі робіць код прыемней на вачы, дзеяце адзячна.
Савэцкі JavaScript не значыць неабходнасць вялікай кількасці функцыональных тэхнік
Існуе ўжо адна звычная прычына ненавоколлічной складнасці: падазрэнне, што савэцкі JavaScript трэба пісаць у высокай меры функцыональным стылем.
Часта можна зустрэць ўсё такое:
const result = users
.filter(user => user.active)
.map(user => ({
...user,
displayName: `${user.firstName} ${user.lastName}`
}))
.reduce((groups, user) => {
const key = user.department;
groups[key] ??= [];
groups[key].push(user);
return groups;
}, {});
Сама по сабе ў гэтым няма нічога пакладзенага.
Але лёгка забыць, што простая петля ёсць абсалютна дыяктуальны JavaScript.
Гэтае выкананне таксама можа быць цілком разумным:
const result = {};
for (const user of users) {
if (!user.active) continue; const department = user.department; if (!result[department]) {
result[department] = [];
} result[department].push({
...user,
displayName: `${user.firstName} ${user.lastName}`
});
}
Версія з петлёй запоўнюе больш ліній.
Яна таксама може быць простэйшай для аналізу пад час дэбагавання.
Професійны код ацэнюецца не па колькасці ліній, якія ён викорыстоўвае.
Ён ацэнюецца па тым, як мало непатрэбных канцэптуальных зусіль ён выклекае у таго, хто яго чытае.
Іноды map, filter і reduce зменшуюць гэтыя зусіль.
Іноды петля выканае задачу краща.
Важлівей знать, калі вжываць той чы іншы інструмент, чым запамяцваць кожны доступны метод масів.
Модэль об’ектаў JavaScript становіцца простейшай, калі перастаеш з нею борацца
Значная частка плутання ў зв’язку з JavaScript выходзіць з прагнення прымусіць яго пасаць у ментальную модель іншага языка.
Об’екты JavaScript можу проста хаваць данні:
const user = {
name: "Sarah",
age: 31
};
Яны таксама можу хаваць функцыі:
const user = {
name: "Sarah",
greet() {
return `Hello, ${this.name}`;
}
};
Можна задаць класы:
class User {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
Але класы не ўсюды є неабходнымі.
Звычны об’ект у поўнай злучэнні з функцыяю-фабрыкантом часта ўсё такі ж зрозумілы:
function createUser(name) {
return {
name,
greet() {
return `Hello, ${name}`;
}
};
}
Ні адны стыль не є кращым у кожнам случае.
Праўая майстэрнасць — гэта здатнасць распізнаваць, калі конкрэтны фрагмент коду насправды патрэбуе чагосьці.
Класы маюць сэнс, калі трэба кераваць ідэнтычнасцю, поведенням, жыцёвым циклам, спадчынай чы абгортаванням об’ектаў.
Звычныя об’екты лепей падходзяць для простых даных.
Функцыі лепей падходзяць для трансформацый.
Модулі зазвычай падходяць для абгранацый меж частак системы.
Не трэба прыводзіць кожную концэпцыю у клас толькі таму, што язык гэта падтрымляе.
Сістэма модуляў належыць да сярод найсильнейшых фічараў JavaScript
Натыўныя модулі тыха рашаюць проблему, якая раней стварала вельмі большую непатрэбную складнасць.
Разглядзім такі патэрн:
// math.js
export function add(a, b) {
return a + b;
}
У пару з:
// app.js
import { add } from "./math.js";
console.log(add(2, 3));
Такая налада стварае чыстую абгранацыю залежнасцяў. Модуль, які імпортуе, берае толькі тое, што яму практычна трэба. Самыя залежнасці застаюцца виднымі ў кодзе. Можна працаваць з функцыяй окрема. І для всіга гэтага не трэба запхваць усё ў вялікі глобальны прастор імен.
Тое, што гэта такое значны, — гэта тое, што для практыкавання модулярнасці не трэба жадных фреймворкаў. Сам язык дазволяе чытка паводліць межы між разнымі часткамі вашай системы. Проект можа быць арганізаваны так:
src/
users.js
orders.js
payments.js
validation.js
config.js
app.js
без прымусу кожнага файлу дэманстраціяваць патерн проектавання.
Добра структураванный модуль зазвычай заўсёды робіць тры рэчы зрозумелымі проста праз яго адзірванне: калькі функцыянальнасці да яго належыць, калькі частакі гэтай функцыянальнасці ён робіць доступнымі званутай стороне, і калькі іншыя часткі коду яму патрэбны для роботы.
Калі гэтыя рэчы стануць зрозумелымі, ваш проект вже будзе ў прыемным стане.
Не кожнае трэба абстрагаваць
Гэта можа быть найважнейшы момент усюды.
Развіццялічыя часто пачынаюць абстрагавація як толькі пазнаюць павтарэння коду. Але сама павтарэнне не завжды є проблемай, якую трэба рашыць.
Скажым, у вас ёсць:
const user = await fetch("/api/users/42");
const order = await fetch("/api/orders/18");
У певны момент вы можете заўважыць, што логіка обробкі адпаведзей продовжае павтарацца. Гэта заўважэнне можа падсунуць вам ідею напісаць:
async function getJson(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
} return response.json();
}
Што дазволяе спростіць код да:
const user = await getJson("/api/users/42");
const order = await getJson("/api/orders/18");
Такая абстракцыя заслуговае на свое месца — у яе ёсць чыстая функція.
Тепер параграфуйце гэта з стварэнням універсальнага фабрыкі запытоў, шаблона стратэгіі запытаў, інтарфейса рэпазітарыя, адаптара транспорту, обгоркі адпаведзі і цэлага шару службы яшчэ до таго, калі вы напісаеце другі вызов API. У такім случае вы на самай працы не зменшылі складнасць — вы проста перанеслі яе ў саму архітектуру.
Гэты шаблон часта з’яўляецца ў кодавых базах на JavaScript. Разработчык заўважвае два падобныя фрагменты коду і адразу ж прыначаеся дзейсці ў гіпотэтычныя майбутнія сценарыі. Хорашая інжынерная практыка часта выклікае працоўнае падходжэнне.
Чакайце, пакуль павтарэнне не стане настолькі явным, што адпрацоўка пакажа ся сама.
Абстракцыі, якія ўводзяцца занадта рано, часта вельмі складна адмахнуць пазней, галоўная прычына — ў канцэ народ не можа з упевненасцю сказаць, чы робяцца яны ўсё такі ж корыстная работа.
Браузер вже робіць для вас многа
Савременны JavaScript можа здавацца болей складным, чым трэба, часткова таму, што разработчыкі трапляюцца не ведаюць, сколькі можа зробіць сама платформа.
Вы можете безпасэродна маніпуляваць DOM. Можаце прыўязваць слухачы змаганняў. Можаце выканаць запыты сеті. У вас є доступ да Web Storage. Можаце стварыць Web Workers. Можаце ачыніць з’єднання WebSocket. Можаце кераваць історыяй браузера. Можаце працаваць з натыўнымі формамі.
Усё гэта доступна без неабходнасці выкарыстоўвання спецыяльных пакетаў для кожнай дробнай задачы. Напрыклад:
const button = document.querySelector("#save");
button.addEventListener("click", async () => {
const response = await fetch("/api/save", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ message: "Hello" })
}); if (!response.ok) {
throw new Error("Save failed");
}
});
Это ўсёя функцыональная взаімадзея ў рэальным прыкладным програме, без викорыстання якога-лібо фрэймворку.
Нічыга з гэтага не ўскладнюе викорыстання фрэймворкаў — яны рашаюць рэальныя проблемы. Але асновная платформа заслуговае на большое визнанне, чым яго часта атрымлеў. Калі вы зрозумеете, што браузер і мова вялікім бесплатным спосабам даўаюць вам, вы будете аднакоўсі больш правільна выбіраць, за шта насправды павінен відпавядаць фрэймворк.
Залежнасці маюць свой кост
Інсталляванне пакета можа заўсёды захаваць ваш час. Але гэта таксама можа прымусіць вас да давялогаў на дужы час з прычыны чаго-то, што вы самі моглі бы напісаць за дзесять рэядоў коду.
Возьмім маленькую утиліту, напрыклад:
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
Ўсіма верасцямі, вам можа не патрабавацца зовнішняя пакета для гэтаго. Але такі рашчынкі, як аутентыкацыя, крыптаграфія, складная арыметыка дат, кліенты базаў дадзеных, обробка зображэнняў і розвітаная логіка верыфікацыі, належаць да абсалютна іншай катэгорыі.
Урок тут не ў тым, "восьбаўляйцеся ад залежнасцяў за ўсю цену". Це пра тое, каб разумець, сколькі на самай працоўцы кожная з іх.
Кожная залежнасць прыносіць:
- постаўленую падтрымку
- наследкі для безпекі
- работу з апдэйтом версіі
- дакументацыю, якую трэба чытаць
- дрэва транзітных залежнасцяў
- вплыв на процес стварэння
- ўсё большую абстракцыю, якую трэба выучыць
Найлепшыя развіцелі JavaScript — это не тые, хто запамятаваў найбольш пакетаў npm. Це тые, хто можа з’ясавіць, калі пакет на самай працоўцы не патрабуецца.
TypeScript прыносіць адчуваемую складнасць, але гэта абсалютна іншая тэма
Для большых кодавых баз TypeScript можа значна паспрабавіць падбярэць кантэкст развіцці. У той жа час ён дагаўае яшчэ адны слой да самай мовы.
Вы ў канцэ вырашаеце пісаць такое:
type User = {
id: number;
name: string;
email: string;
};
А таксама:
function getUser(id: number): Promise<User> {
// ...
}
Гэта мае рэальную цэннасць. Але важна адзеліць складнасць, якая выходзіць з самай мовы, ад складнасці, якая выходзіць з налаштаванняў вашых інструментаў.
Сам JavaScript не стае сложней проста таму, што да яго дадаюцца пераканальнік типаў, лінтар, збірчык модуляў, фрэймворк UI, автаматызаваны набір тэстаў і калькі плагінаў для будавання. Тое, што стае болей вырашэнным, — это ваша серавысь для развіцці, і гэтая вырашанасць абавязкова можа дапамогчы.
Але наявна сложная суцэльнайка інструментаў не павінна прыводзіць вас да вывару, што язык, які стоіць за ёю, ў сваей сутнасі є складным. Часта на самай працэ ён ўсё-такі дасыць просты.
Праўая майстэрнасць — гэта выбіранне самай простай, але корыстной абстракцыі
Адны і тыя ж принцыпы праўілі ўсё, што было обгаворана да гэтага часу.
Напісанне хорашага JavaScript малая ступеня звязана з володзеннем усімі доступнымі функцыямі, а большая — з выборам самага простага інструмента, які выканае задачу.
Патрэбна ператворэнне содержымоў масівы? Вжывайце map.
Патрэбна сузіць набор значэнняў? Вжывайце filter.
Патрэбна аранжаванне асінхронных задач? Вжывайце async і await.
Патрэбна павторна вжываемая логіка з чысткімі межамі? Напісайце функцыю або модуль.
Патрэбна колекцыя, дзе ключы не обмежаны толькі стрэлкамі? Паглядзіце на Map.
Патрэбна гарантія унікальнасці? Адзірніце Set.
Патрэбна абярактная доступа да ўласнасці, якая можа не існаваць? Іспользуйце опцыйнае ланкуванне.
Патрэбная стандартная значэння толькі калі ўласнасць null або undefined? Іспользуйце ??.
Патрэбны просты контейнер для дадзеных? Дастаточна об’екта.
Патрэбна болей развітая праця і ідэнтычнасць, звязаная з вашымі дадзеннямі? Клас можа падойсці.
Патрэбна структурацыя сапраўдна большога прыемніка? Тады варта рассмотрзець фрэймворк.
Зверніце увагу на гэтыя паслядовасці.
Спачатку вы начынаеце з самай мовы.
Потым адзірнуецеся, што вяліканка вже прысутняйце.
Потым — маленькія, спецыяльна створаныя аб’екты-абстракцыі.
Потым — зовнішнія бібліятэкі.
Потым — фрэймворкі.
Змена гэтай паслядовасці ўсё часта прыводзіць да непатрэбнай складнасці.
Простата — гэта не абсэнцыя інжынерных рашэнняў
Існуе распашчастая, але хыбная думка пра тое, што на самай працо значыць «просты» код.
Дзеяныя людзі асоцыююць простата з неабавнасцю.
Гэтая асоціяцыя не ўсходзіць.
Паглядзіце на каго-небудзь, які новачак у гэй працы, і ён пішае нечта такое:
function process(data) {
// everything
}
На першы погляд гэта выглядае мінімалістычна, але як толькі код расшыроўваецца, яго становіцца справжня праця падтрымваць.
Болей абавны разработчык можа замест таго разлучыць тую ж логіку на пяць маленькіх модуляў, кожны з якіх мае чыста визначаную межу.
У такім разе є больш элементаў, але на самай працо легча ўсё разумець.
Это іншы, болей значымы вид простата.
Мэтай не ў тым, каб зменшыць колькість файлаў, спіс залежнасцей чы колькість ліній коду.
Мэтай ў тым, каб пазбавіцца сложнасці, якая не мае падставы існаваць.
Гэта разыяўленасць становіцца ўсё бол важлівайя, калі база коду расте.
Скрыпт, які складаецца толькі з двадзяці ліній, все ўсё можа быць калючым для розумэння.
Програма з двамя тысячамі ліній, на дзіво, можа быць простай у вучэнні.
Рашаючы фактар зазвычай не ў абсалютной колькасці коду.
Это тое, чы розумець можна асновную модэль, якая лежыць у основе коду.
Перастаньце спрыятаць кожную новую функцыю як обавязковыя знання
JavaScript развіваецца быстра, і гэты темп стварае сваёродны стрэс.
Вы прызвыкаецеся да певнага спосабу ведэння роботы, а за калькі месцацоў іншы падход становіцца домінуючым у всіх дыскусіях.
Паўстае новая фрэймворк.
Новы рантайм почынае набіраць популярнасць.
Новы шаблон атрыбутаў становіцца трэндам.
Паўстае новы элемент синтаксісу.
Лёгка ўявіць, што вы постаўна атрымліваеце пазад.
Але, шансава, гэтага няма.
Вам не трэба адразу запам’ятаваць кожную новую тэхніку JavaScript, як толькі хтось паблікуе пра ёй пастку.
Усё радзей інвестуйце ў фундаменталы.
Развійце навыкі асінхроннага програмавання.
Развійце розумэнне концепцыі дыяпазону.
Развійце розумэнне клаусураў.
Развійце розумэнне об’ектаў.
Развійце розумэнне модуляў.
Развійце розумэнне цыклу змаганняў.
Развійце розумэнне праграм.
Развійце навыкі карэткага адкульгавання памылак.
Развійце розумэнне API-ў, якія выканаюцься вашым браузерам або средой выканання.
Развійце навыкі аналізу таго, як даны праходзяць через прыемлік.
Ляч тады, калі з’являецца рэальная проблема, якая вымагае новых інструментоў.
Такі падход дапамагае стварыць навыкі, якія застойваюцца ў часе.
Знаныя, атрыбутуюцые конкрэтнаму фреймворку, можаўць стаць застарэлымі.
А моцны псыхічны модэль пра тое, як працуюць прыемлікі, зазвычай не застарэўвае.
Найлепшы код на JavaScript частаца выглядае простаў
Разработчыкі зазвычай з часам розумеюць гэта.
Код, які лёгка ў падтрымцы, рэдка калі вражае каго-небудзь пасля першага прачытання.
У ёму няма пяці абстракцый, якія стояць адна на другой.
Ёму не трэба схемы, каб першая функцыя стала зрозумелай.
У ёму не викорыстоўваюцца всі функцыяны, якія былі даданы ў пасляпэльных версіях мовы.
Часта ён проста выглядае звычайна.
Гэта не крітыка, а сіла.
Калі вы ачынайце файл, мета становіцца негайна ясной:
import { getUser } from "./users.js";
export async function loadProfile(id) {
const user = await getUser(id); if (!user) {
throw new Error("User not found");
} return {
name: user.name,
email: user.email
};
}
Практычна няма нічога, што трэба декодаваць.
Функцыя запрашвае данні аб корыстніку.
Яна пераканальваецца, чы розшук успэсны.
Потым яна вяртае тыя данні, якія насправды патрэбны.
У ёй няма нічога, што прагне падтвердзіць, насколькі хутрачны ўсунуўшый яе автар.
Гэта проста ўтримоўвае чытальніка ад неканэйсарнай працы, і гэта ў дзесяткі разоў ценнейшая якасць у коде.
Сучасны JavaScript простыяй за нашы проекты
У JavaScript таксама є своія справжнія недагодзі. У кожнай мове ёсць.
Але вялікая частка складнасці, яку люди прызначаюць „сучаснаму JavaScript“, на самай працы не выходзіць з самой мовы.
Яна выходзіць з слоёў, якія накладаюцца на ёй.
Фреймворкі.
Системы стварэння.
Залежнасці.
Канвэнцыі.
Абстракцыі.
Інструменты.
Архітэктурныя выборы.
Дзеякі з гэтых слоёў справды є падставленыя.
Іншыя — ні.
Правильны вопыт не ў тым, чы розрабочы інструмент можна счытаць сучасным.
Правильны вопыт — чы ён даследжвае складнасць для конкрэтной задачы, якая стоіць прымаў.
Перш чым шукаць яшчэ адну залежнасць, пераканайцеся, чы не падкрывае яна ўжо потрэбу платформай.
Перш чым ввести яшчэ адну абстракцыю, пераканайцеся, чы рэальна тая дуплікацыя, якую вы намагаецеся рашыць.
Перш чым дадаць яшчэ адной архітектурнай складовай, чытка разберыцеся, якія проблемы ёй задумана запобегчы.
Перш чым выбраць яшчэ адну фреймворк, разберыцеся, яку самэўлічную проблему у вашай ныяней наладзе вы насправдэ працуеце над рашэнням.
І перш чым выйсці да заключэння, што сам JavaScript занадта складны, спробуйце рашыць проблему, выкорыстоўваючы толькі сам язык і платформу, на якой ён працюе.
Рэзультат можа вас здываць.
Язык часта ёстся самай простой часткай усіяго рашэння.
Саме развіцелі продовжаюць дадаваць да яго ўсё больш складных элементаў.
Інодзе найболей прыгожы крок — гэта адну складовую адняць, а не дадаць новую.
Лепшы JavaScript — это не той код, які выкарыстоўвае найбольшае количество інструментаў.
Это код, у якім кожны включаны інструмент справжняя заслужыў сваё месца.