Oops, I did it again: адладка распаўсюджаных памылак у JavaScript
Часам напісанне кода JavaScript даецца складана, а часам і проста палохае, што знаёма шматлікім распрацоўнікам. У працэсе працы непазбежна ўзнікаюць памылкі, прычым некаторыя з іх паўтараюцца часцяком. У артыкуле, разлічаным на пачаткоўцаў распрацоўнікаў, распавядаецца аб гэтых памылках і спосабах іх рашэння. Для навочнасці назвы функцый, уласцівасцяў і аб'ектаў узяты з папулярнай песні. Усё гэта дапамагае хутка запомніць, як выпраўляць распаўсюджаныя памылкі.
Нагадваем:для ўсіх чытачоў "Хабра" - зніжка 10 000 рублёў пры запісе на любы курс Skillbox па промакодзе "Хабр".
let girl = {
name: "Lucky",
location: "Hollywood",
profession: "star",
thingsMissingInHerLife: true,
lovely: true,
cry: function() {
return "cry, cry, cries in her lonely heart"
}
}
console.log(girl.named.lucky)
Прыклад кода, паказанага вышэй, выдае памылку Uncaught TypeError: Cannot read property 'lucky' of undefined. Праблема ў тым, што ў аб'екта girl няма ўласцівасці named, хоць ёсць уласцівасць name. А паколькі ўласцівасць girl.named не вызначана, то нельга і атрымаць да яго доступ, бо фармальна яно не існуе. Але вось калі замяніць girl.named.lucky на girl.name, тое ўсё запрацуе і праграма верне Lucky.
Больш падрабязна пра ўласцівасці можна пачытаць тут.
Спосабы ўхілення памылак TypeError
Памылкі TypeError з'яўляюцца, калі праграміст спрабуе выканаць дзеянні з дадзенымі, якія не адпавядаюць вызначанаму тыпу. У якасці прыкладу можна ўзяць ужыванне .bold(), запыт уласцівасці undefined або выклік функцыі, якая на самой справе не з'яўляецца функцыяй.
Так, калі паспрабаваць выклікаць girl (), то з'явіцца памылка Uncaught TypeError: yourVariable.bold не працуе, і дзяўчынка не функцыя, паколькі на самой справе выклікаецца аб'ект, а не функцыя.
Для таго, каб ухіліць памылкі, трэба вывучыць зменныя. Дык, што такое girl? А што такое girl.named? Даведацца гэта можна, калі прааналізаваць код, вывесці зменныя з дапамогай console.log з, камандай debugger або выклікам імя зменнай у кансолі. Трэба пераканацца, што ёсць магчымасць апераваць тыпам дадзеных, які змяшчаецца ў зменнай. Калі ён не падыходзіць, зменіце яго, напрыклад, дадайце ўмову або блок try..catch - і атрымаеце кантроль над выкананнем аперацыі.
Перапаўненне стэка
Калі паверыць аўтарам слоў песні Baby One More Time (гэта Брытні Спірс, ага), то слова hit у дадзеным кантэксце азначае жаданне спявачкі, каб ёй патэлефанавалі яшчэ раз (тут тлумачэнне самога кантэксту песні, — заўв. перакладчыка). Цалкам магчыма, што гэтае жаданне прывядзе да павышэння колькасці званкоў у рэальным жыцці. Але ў праграмаванні гэта рэкурсія, здольная выклікаць памылку ў выпадку перапаўнення стэка выклікаў.
Памылкі выглядаюць наступным чынам:
Error: Out of stack space (Edge)
InternalError: Mut recurso (Firefox)
RangeError: Maximum call stack size exceeded (Chrome)
Перапаўненне стэка адбываецца, калі распрацоўнік не ўлічыў базавы выпадак у рэкурсіі ці ж калі код не звяртаецца да прадугледжанага выпадку.
function oneMoreTime(stillBelieve=true, loneliness=0) {
if (!stillBelieve && loneliness < 0) return
loneliness++
return oneMoreTime(stillBelieve, loneliness)
}
У дадзеным выпадку stillBelieve ніколі не можа прыняць значэнне false, таму кожны раз будзе адбывацца выклік oneMoreTime, але выкананне функцыі так і не скончыцца.
Калі ж пачаць спадзявацца на двух сяброў, гэта знізіць loneliness (адзінота), і званка можна будзе не чакаць.
function oneMoreTime(stillBelieve=true, loneliness=0) {
if (!stillBelieve && loneliness < 0) return
loneliness--
stillBelieve = false
return oneMoreTime(stillBelieve, loneliness)
}
У якасці прыкладу можна прывесці выпадкі з бясконцымі цыкламі, калі сістэма не выдае паведамленне аб памылцы, а старонка, на якой выконваецца JavaScript-код, проста завісае. Так здараецца, калі ў цыклу while няма ўмовы завяршэння.
let worldEnded = false
while (worldEnded !== true) {
console.log("Keep on dancin' till the world ends")
}
Вырашыць праблему можна наступным чынам:
let worldEnded = false
while (worldEnded !== true) {
console.log("Keep on dancin' till the world ends")
worldEnded = true
}
Адладка бясконцых цыклаў і рэкурсій
Калі ўзнікла праблема з бясконцым цыклам, у Chrome або Edge трэба зачыніць укладку, а ў Firefox - акно браўзэра. Пасля гэтага трэба старанна прааналізаваць код. Калі не атрымалася знайсці праблему, варта дадаць каманду debugger у цыкл ці функцыю і праверыць значэнне зменных. Калі вынік не адпавядае чаканаму, тое заменны, гэта можна зрабіць лёгка.
У прыкладзе, які паказаны вышэй, debugger варта дадаць першым радком функцыі ці цыклу. Затым трэба адкрыць дэбаг-укладку ў Chrome, прааналізаваўшы зменныя ў scope. Пры дапамозе кнопкі next можна адсачыць іх змену пры кожнай ітэрацыі. Зрабіць усё гэта проста, і ў большасці выпадкаў праблема знаходзіцца.
Адна з найбольш распаўсюджаных памылак у JavaScript - SyntaxError. Пазбегнуць іх дапамогуць пашырэнні тэкставага рэдактара. Так, Bracket Pair Colorizer адзначае дужкі ў кодзе рознымі кветкамі, а Prettier ці падобная прылада аналізу дае магчымасць хутка знайсці памылкі. Лепшы варыянт, каб знізіць верагоднасць з'яўлення SyntaxError - мінімальная ўкладзенасць.
Падзяліцеся ў каментарах: што вы робіце для таго, каб не дапускаць памылак ці хутка выяўляць і ліквідаваць іх?