Zakres zmiennych, hoisting – co warto wiedzieć?

Elevator

Koniec wakacji, czas brać się do roboty 🙂 W tym wpisie postaram się krótko i treściwie omówić zakres zmiennych i hoisting w JavaScript.

Zakres zmiennych

Zakres zmiennych w JavaScript, to temat nieco skomplikowany. Programista, który dopiero zaczyna swoją przygodę z JSem, może być w niemałym szoku próbując okiełznać tajniki sztuki.

for (var a = 0; a < 5; a++) {}
console.log(a); // 5

Na początek stwórzmy standardową pętlę for, w której deklarujemy zmienną a = 0. Poniżej odwołujemy się do tej zmiennej i jako rezultat dostajemy 5.

Wniosek: Deklaracja zmiennej poprzez słowo kluczowe var powoduje zalokowanie miejsca w pamięci i zachowanie stanu pomimo zakończenia pętli. Zmienna jest widoczna w kontekście funkcji.

Na ratunek let i const

W standardzie ECMAScript 2015 (ES6) wprowadzone zostały nowe słowa kluczowe let i const. Służą do tego samego co var, ale mają ograniczony zasięg.

let is the new var.

for (let a = 0; a < 5; a++) {}
console.log(a); // Uncaught ReferenceError: a is not defined

Jak widzimy w powyższym przykładzie, zamiana var na let daje wymierny skutek. Nie mamy dostępu do zmiennej poza blokiem for. O to nam chodziło… wykorzystujemy zmienną z kontekstu blokowego.

Jak się ma do tego const?

Deklaruje nazwaną stałą tylko do odczytu – MDN

Nie możemy ponownie przypisać wartości do consta:

const a = 7;
a = 5; // Uncaught TypeError: Assignment to constant variable.

Nie możemy też ponownie zadeklarować stałej:

const a = 7;
const a = 5; // Uncaught SyntaxError: Identifier 'a' has already been declared

JS ma jednak swoje wymagania, a const może sporadycznie piszących w tym języku wprowadzić w błąd.

const a = [];
console.log(a); // []
a.push(2);
console.log(a); // [2]
a.push({ a: 3 });
console.log(a); // [2, {a: 3}]

W JavaScript const NIE oznacza deklaracji stałej wartości, lecz deklarację stałej referencji. W przypadku typów prymitywnych const zachowuje się tak jak oczekujemy. Przy typach złożonych mamy możliwość podmiany zawartości.

Idealnie obrazuje to przykład powyżej. Tworzymy stałą a = [], następnie poprzez metodę push dodajemy pierwszy element tablicy, itd.

Hoisting

Temat hoistingu jest często poruszany, zarówno na branżowych spotkaniach jak i rozmowach kwalifikacyjnych. To jeden z feature’ów JSa, o którym wszyscy słyszeli lub wkrótce usłyszą.

Hoisting, spolszczona nazwa windowanie, to mechanizm pozwalający na przeniesienie deklaracji zmiennych oraz metod na początek funkcji.

a = 5;
var a;
console.log(a); // 5

i

simpleFunction(); // hoisting

function simpleFunction() {
  console.log('hoisting');
}

W przykładzie pierwszym do zmiennej a przypisujemy 5, następnie ją deklarujemy. Log w konsoli daje rezultat 5. Drugi przykład, to wywołanie metody przed deklaracją. Rezultat taki sam jak wcześniej. Hoisting zadziałał.

Przy deklaracji zmiennych za pomocą słowa kluczowego let, hoisting zachowuje się bardziej przewidywalnie.

a = 5;
let a; // ReferenceError: a is not defined

Strict mode

Strict mode (tryb ścisły) to jeden z feature’ów ES5. Wprowadza kilka zmian do domyślnej semantyki JavaScript:

  1. Pozwala wyeliminować ciche błędy (ang. silent errors).
  2. Pozwala wyeliminować błędy, które uniemożliwiają optymalizację JSa przez przeglądarki.
  3. Uniemożliwia stosowanie składni mogącej wystąpić w kolejnych odsłonach ECMAScript.

Temat został pobieżnie wywołany, przy okazji hoistingu, nie bez przyczyny. Strict mode nie zezwala na skorzystanie ze zmiennej, dopóki nie zostanie zadeklarowana.

Warto przeczytać:

ECMAScript 2016 – ES 7 – zaczynamy!

ecmascript 2016

ECMAScript to standard programistyczny i wyrocznia dla wielu języków skryptowych (m.in. JavaScriptu). Ukończony w czerwcu tego roku ECMAScript 2016 (ES7) jest najnowszą wersją owych standardów. Póki co pozostaje tylko ciekawostką i punktem zaczepnym dla geeków programowania.

Mimo, że poprzednia wersja ECMAScript została wydana już rok temu, to do tej pory nie doczekała pełnego wsparcia ze strony przeglądarek. Kod jest najczęściej przetwarzany do wersji ES5, która zapewnia, większą stabilność aplikacji.

ECMAScript 2016 compatibility table
ES6 compatibility table

ES7 – szybki przegląd

Wersja siódma standardu, znana pod oficjalną nazwą ECMAScript 2016 została sfinalizowana w czerwcu tego roku. Nie wnosi ona tak ogromnych zmian jak poprzednia wersja, nie ma tutaj tak przełomowych rozwiązań jak na przykład arrow function.  Są za to proste rozwiązania, które z łatwością będzie można wykorzystać w codziennej pracy. Wyjście specyfikacji ES7 jest także odpowiedzią na błędy zgłaszane prze community. Trend wyraźnie wskazuje na to, iż wpierw należy zapewnić pełne wsparcie przeglądarek oraz rozwiązać istniejące problemy, a dopiero później wprowadzać kolejne nowinki.

ECMAScript 2016 – Features

Dobrą wiadomościa dla ludzi zagubionych w czeluściach JavaScriptu jest fakt, że wersja ECMAScript 2016 wprowadza tylko dwie zasadnicze zmiany: Array.prototype.includes() oraz exponentiation operator.

Array.prototype.includes()

Metoda includes() sprawdza czy tablica zawiera zadany element.

Array.prototype.includes(value : any) : boolean

Exponentiation operator

Exponentation operator zwraca taki sam wynik jak znana wszystkim metoda Math.pow(x, y). Pierwszy argument zostaje podniesiony do potęgi, która jest zadeklarowana w drugim argumencie.

Dokąd zmierzamy

Mnogość zmian oraz szeroki wachlarz możliwości jakie daje ECMAScript 6 budzi różnorakie emocje. Sceptycy twierdzą, że jest to przerost formy nad treścią i JS nigdy nie zostanie “prawdziwym” językiem programowania. Innych z kolei przeraża ogrom zmian. Ludzie związani z szeroko rozumianym front-endem często zaś popadają w huraoptymizm widząc jakie możliwości dają coraz to nowsze wersje specyfikacji ECMA. Pamiętajmy jednak o tym, że tak długo jak przeglądarki nie będą w stu procentach kompatybilne ze standardem, tak długo nie będziemy mogli korzystać z dobrodziejstw jakie zostają na dostarczone (chyba, że bezustannie będziemy korzystać z kompilatorów).

Źródła:

Nie pisz w kółko tych samych funkcji, wykorzystaj moc Lodasha

Utility

Lodash

Ciągłe pisanie tych samych funkcji jest uciążliwe i frustrujące. Poznaj bibliotekę Lodash i przestań bezmyślnie powielać trywialny kod.

Lodash jest niskopoziomową biblioteką, która poprzez zwięzłe metody może znacząco ułatwić codzienne życie programistom JavaScript. Operacje na tablicach, obiektach czy łańcuchach znaków stają się przez to o wiele prostsze i znacząco przyspieszają rozwiązywanie problemów.

Lodash został utworzony jako fork projektu Underscore. Tempo rozwoju oraz wprowadzane funkcjonalności przyniosły mu olbrzymią popularność. W przeciwieństwie do większości javascriptowych bibliotek, Lodash unika metod iteracyjnych, na rzecz uproszczonych pętli, co przekłada się na mocno odchudzony kod. Lodash jest lekki. Pełna wersja biblioteki waży ~21 kB po minifikacji oraz kompresji gzip.

Poniżej przedstawiam 5 metod, dzięki którym zaoszczędziłem czas i przestałem przepisywać funkcje w moich aplikacjach.

Wybór pseudolosowej liczby z zadanego przedziału

Wybór pseudolosowej liczby za pomocą metody _.random jest wskazany, jeżeli szybko chcemy wylosować liczbę z zadanego przedziału i pozostawić sobie furtkę do zmiany tejże metody w przyszłości. Deklarując jeden parametr, funkcja uzna go za wartość maksymalną. Deklarując dwa parametry, funkcja przypisze je kolejno do minimum i maksimum zadanego przedziału. Liczby zmiennoprzecinkowe można uzyskać poprzez dodatkowy parametr – typ boolowski – true (brak parametru  równoznaczny jest z domyślnym – false).

Pozostałe przypadki użycia funkcji _.random

Wybór pseudolosowej pozycji z tablicy

Oprócz typowej funkcji _.random, Lodash oferuje możliwość pobierania przykładowych danych. Metoda _.sample jest świetnym sposobem na pobranie pseudolosowego elementu z danego zbioru (Array | Object).

Pętla for dla n powtórzeń

Pętla for jest poligonem doświadczalnym dla wszelkich niskopoziomowych bibliotek. Gdy używamy zwykłej pętli for w celu iteracji, jesteśmy zmuszeni zadeklarować dodatkową zmienną. Za pomocą Lodasha i metody _.times pozbywamy się tej zmory, przez co metoda wydaje się zdecydowanie przyjemniejsza dla oka.

Różnica pomiędzy dwiema tablicami

Wyraźną różnicę przyjdzie nam zaobserwować, gdy przyjdzie nam użyć metody _.difference. Funkcja zwraca wartości z pierwszej tablicy, które nie zostały umieszczone w drugiej tablicy (unikalne względem porównywanej tablicy). Nawet Array.prototype, który wykorzystywałem najczęściej wypada blado w porównaniu z dedykowaną metodą Lodasha.

Łączenie obiektów

Doskonałym pomysłem, gdy chcemy połączyć obiekty, jest użycie metody _.merge. Metodę można wykorzystać na wiele sposobów. Dzięki dziedziczeniu właściwości obiektów, operacje na obiektach stają się bardzo proste.

Lodash – podsumowanie

Lodash jest przydatną biblioteką, która pomaga zaoszczędzić sporo czasu programiście. Zmniejsza ilość napisanych linijek, co przekłada się bezpośrednio na klarowność tego, co napiszemy.

Używam go od niedawna, ale już zauważam różnicę, gdy stosuję go w projektach. Lodash wymusza na mnie programowanie funkcyjne. Pisanie obszernych modułów czy długich metod traci sens. Wzrasta świadomość tego co piszę, jak działają poszczególne metody, a w rezultacie cała aplikacja.

P.S. Na chwilę pisania artykułu JSFiddle ma dostępną tylko jedną wersję biblioteki Lodash (Lo-Dash 2.2.1).