Publikoval Michal Kočí dňa 29.5.2016 o 15:00 v kategórii JavaScript
V JavaScripte máme boolean dátový týp, ktorý môže nadobúdať hodnoty true a false, to je veľmi podobné aj iným programovacím jazykom. Čo však máme navyše je Truthy a Falsy, čo sú síce podobné hodnoty, ale ich využitie je oveľa širšie. Poďme sa na ne pozrieť.
...ale v JavaScripte má všetko okrem svojej vlastnej aj pravdivostnú hodnotu. Tieto hodnoty sa volajú Truthy a Falsy. A najlepšie na nich je, že ich vieme použiť všade tam, kde by ste mohli použiť Boolean. Pozrime sa najskôr ale na to, čo je Truthy a čo Falsy.
Hodnotu Falsy, teda akúsi obdobu hodnoty false
, majú:
false
0
)''
)NaN
(not a number)null
undefined
Hodnotu Truthy (obdobu true) má všetko, čo nemá hodnotu Falsy. Teda napríklad:
true
Určite viete, že if
či while
potrebujú k svojmu fungovaniu výraz vracajúci Boolean
a na základe jeho hodnoty sa patričný blok vykoná alebo nevykoná. Tak to funguje zrejme v každom programovacom jazyku.
V JavaScripte je to trochu inak. if či while neočakávajú Boolean
ale pravdivostnú hodnotu. A čo má v JavaScripte pravdivostnú hodnotu? Presne tak, všetko.
Poďme na príklad. Potrebujete spustiť kód iba ak má pole arr aspoň jeden prvok. Jednoduché:
if(arr.length > 0) { console.log('Neprazdne pole'); }
Uvedený kód sa dá však zapísať kratšie ovšem s úplne rovnakou funkcionalitou. Využijeme vedomosť, že nula je Falsy. Preto môžeme kód prepísať nasledovne.
if(arr.length) { console.log('Neprazdne pole'); }
Pokiaľ je veľkosť pola (arr.length
) nula, t.j. pole neobsahuje žiaden prvok, hodnota vráti Falsy. if
blok sa teda nevykoná, lebo if
očakáva Truthy/Falsy hodnotu (a nie true
/false
). Ak pole obsahuje aspoň jeden prvok, hodnota arr.length
bude nenulová, t.j. Truthy a teda blok sa vykoná.
Možno si vravíte, že prvý zápis je opisnejší, jasnejší či zrozumiteľnejší. Že viete presne čo sa deje. Kdežto druhý je mierne komplikovanejší na porozumenie. Možno. A možno nie. Záleží na tom, ako JavaScript poznáte. Na druhom zápise nie je nič zlé ani nemorálne.
Môj názor na vec je nasledovný:
Čo je v skutočnosti dôležité? Aby ste zápisu, t.j. Truthy a Falsy hodnotám rozumeli. Ak ich aj nebudete sami používať, verte, že niekto iný bude. A v programovaní často musíte/chcete čítať kód niekoho iného. Takže odteraz vás druhý zápis nemôže prekvapiť.
Chcete sa poriadne naučiť JavaScript a ešte sa pritom naučiť nejaký framework či knižnicu (napríklad Angular či React)? Prídite na niektoré z mojich JavaScriptových školení a naučte sa to rýchlo a jednoducho.
Logické operátory OR a AND tiež v JavaScripte fungujú s Truthy/Falsy hodnotami.
Definovať ich môžeme nasledovne:
||
) vráti hodnotu, ak aspoň jeden výraz je Truthy&&
) vráti hodnotu, ak všetky hodnoty sú TruthyOba operátory navyše skracujú vyhodnocovanie, čo tiež isto poznáte z iných jazykov. Kontrola výrazov končí v momente, kedy je jasný výsledok celého výrazu (vyhodnocuje sa postupne zľava):
Fajn, toto asi nebolo moc prekvapivé, však? Ale všimli ste si, že som slovo hodnotu dal tučným? Náhoda? Omyl? Ani jedno...
V programovacích jazykoch, v ktorých s operátormi OR a AND môžete použiť iba Boolean hodnoty je výsledkom neprekvapivo Boolean hodnota.
V JavaScripte však s OR a AND môžete použiť čokoľvek, očakávajú totiž Truthy/Falsy, čiže čokoľvek. Čo je teda výsledkom celého výrazu?
Zdá sa vám znalosť tejto funkcionality zbytočná? Verte, nie je. Má veľmi praktické využitie, na ktoré sa teraz pozrieme.
Kde sa nám teda tá mierne nudná teória hodí? S operátorom OR sa nám hodí, pokiaľ chceme používať defaultné hodnoty.
JavaScript do verzie ES5 nepodporuje pre parametre funkcií defaultné hodnoty. Ak sme chceli niečo ako defaultné hodnoty používať, museli sme si to zabezpečiť sami.
Predstavte si síce neužitočnú funkciu, pre náš príklad však vhodnú, ktorá vám do konzoly dokáže vypísať jeden a ten istý reťazec požadovane-krát. No a ak volajúci nešpecifikuje koľko krát (alebo povie nula-krát), tak chete reťazec vypísať presne raz. A ak nešpecifikuje reťazec, chcete vypísať Hello World.
function printXTimes(str, times) { var i; if(!str) { str = 'Hello World'; } if(!times) { times = 1; } for(i=0; i<times; i++) { console.log(str); } }
Docela ukecané, však? A to už Truthy/Falsy používame v if
podmienkach. Takto by však mohla vyzerať skrátená verzia, ak použijeme OR operátor:
function printXTimes(str, times) { var i; str = str || 'Hello World'; times = times || 1; for(i=0; i<times; i++) { console.log(str); } }
Kratšie a pravdepodobne aj prehľadnejšie, však? Tak si len v skratke zopakujme, ako to funguje.
Ak voľajúci ako hodnotu parametra str
pošle Falsy hodnotu (null
, undefined
, prázdny reťazec, ...) tak JavaScriptový engine uvidí, že prvá časť výrazu je Falsy a ide vyhodnotiť druhú časť (náš reťazec). A vráti práve túto hodnotu. Jednak preto, lebo táto je Truthy, ale aj keby nebola, tak je to posledná podmienka, takže sa vráti jej hodnota tak či tak.
No a takto jednoducho sme zabezpečili defaultné hodnoty pre naše parametre. Zase platí, pokiaľ s tým nie ste mentálne kompatibilný, kľudne použite ukecanejší spôsob. Ale pamätajte si, ako OR funguje, aby vás neprekvapil nejaký existujúci kód.
Aké je praktické využitie operátora AND? Bez väčšieho napínania vám to prezradím. Je ním volanie callbackov, t.j. volanie funkcií predaných do funkcie.
V JavaScripte často prijímajú funkcie iné funkcie, ktoré majú v istý moment zavolať. Ľudovo sa volajú callbacky. Lenže, nie vždy sú to povinné parametre a vy takúto funkciu chcete zavolať len keď vám bola predaná.
Toto je potom príklad, kde máte funkciu, ktorá vie niečo urobiť a keď je hotová, zavolá callback. Najčastejšie je asi použitie pri asynchronných operáciách (napríklad načítanie dát cez HTTP):
function loadDocument(url, callback) { var r = new XMLHttpRequest(); r.onreadystatechange = function() { if(r.readyState===4 && r.status===200) { var data = JSON.parse(r.responseText); if(callback) { callback(data) } } } r.open('GET', url, true); r.send(); }
Kde v príklade vieme použiť operátor AND? V kontrole, či nám dorazil parameter callback:
function loadDocument(url, callback) { var r = new XMLHttpRequest(); r.onreadystatechange = function() { if(r.readyState===4 && r.status===200) { var data = JSON.parse(r.responseText); callback && callback(data); } } r.open('GET', url, true); r.send(); }
Ako to funguje? JavaScriptový engine sa pozrie na prvú hodnotu. Ak je táto Falsy, skráti vyhodnocovanie, vráti jeho hodnotu a druhý výraz už vyhodnocovať nebude (t.j. nebude sa snažiť spustiť funkciu).
Uznávam, nejedná sa o žiadnu extra veľkú úsporu. Navyše, toto je jedno zo skrátení, ktoré osobne nepoužívam, nepríde mi prehľadné. Ale zase, je dobré o ňom vedieť. A mimochodom, často ho používajú práve minifikátory.
Niekedy sa hodí z pravdivostnej hodnoty (Truthy/Falsy) spraviť pravý Boolean (true
/false
). Napríklad keď výsledok bude ukladať ako JSON. Ako na to?
Operátor logický NOT (!
) slúži na negáciu výrazu. Opäť, pri tradičných jazykoch spraví z true
false
a z false
true
. Lenže v JavaScripte sa dá použiť na ľubovoľný výraz (Truthy/Falsy).
Pokiaľ je výraz Truthy, výsledok aplikovania tohto operátora bude false
. A pokiaľ je Falsy, výsledkom bude true
.
var obj = null; // obj je Falsy
var b = !obj; // b bude true
Toto už skoro robí to, čo by sme chceli, teda mení čokoľvek na Boolean, žiaľ na presne opačnú hodnotu, ako by sme chceli. Ako znegovať výslednú hodnotu? Predsa tým istým operátorom:
var obj = null; // obj je Falsy var b = !!obj; // b bude false
Takže keď budete z Truthy/Falsy hodnoty chcieť získať pravý Boolean, stačia vám k tomu dva výkričníky.
Len pre zaujímavosť, toto fungovanie tiež často používajú minifikátory a v minifikovanom kóde namiesto true
nájdete hodnotu !0
a namiesto false
hodnotu !1
.
Tak ako, dočítali ste až sem? Poznali ste Truthy a Falsy a ich využitie? Podeľte sa v komentároch, ktoré sa vám zdá vhodné a ktoré už až moc nečitateľné...
Ak nechceš premeškať príspevky ako je tento, sleduj ma na Twitteri, alebo ak máš RSS čítačku, môžeš sledovať môj RSS kanál.