Wśród nowinek, które przyniosło ze sobą ES6, nie zabrakło miejsca dla dwóch literałów: łańcuchów szablonowych i oznaczonych łańcuchów szablonowych. Pierwszy z nich łączy klasyczne łańcuchy z obsługą wieloliniowości oraz wstawianiem wyrażeń, znanym chociażby z biblioteki Handlebars.js. Drugi literał, opierający się o funkcje oznaczające, pozwala na dodatkowe przetwarzanie łańcucha przed kompilacją ostatecznej wartości. W tym wpisie postaram się przybliżyć, jaki potencjał kryje się w tych dwóch niepozornych funkcjonalnościach.
Tym razem poruszę następujące zagadnienia:
- Łańcuchy szablonowe:
- Wstawianie wyrażeń
- Wieloliniowe łańcuchy szablonowe
- Oznaczone łańcuchy szablonowe:
- Implementacja funkcji oznaczającej
- Surowe łańcuchy
Zgodnie z obietnicą złożoną we wprowadzeniu do serii, w ostatniej części artykułu znajdziecie odnośniki do praktycznych zadań, pozwalających na przećwiczenie zdobytej wiedzy teoretycznej.
Polsko-angielski słownik pojęć
- Łańcuch szablonowy – Template literal
- Oznaczony łańcuch szablonowy – Tagged Template literal
- Łańcuch – String
Łańcuchy szablonowe
Różnica pomiędzy literałem łańcuchowym a literałem łańcucha szablonowego jest widoczna na pierwszy rzut oka. W pierwszym przypadku, korzystamy z 'apostrofów'
(preferowana praktyka w JavaScript) lub "cudzysłowów"
, które wyznaczają granice naszego łańcucha. Natomiast łańcuchy szablonowe wykorzystują `grawisy`
, po angielsku zwane backticks.
Aby przekonać się, z czym tak naprawdę mamy do czynienia, poprosimy o opinię do kilku znanych i lubianych pomocników.
Jak widać, wartość zmiennej myPreciousSecret
jest finalnie interpretowana przez silnik jako zwykły łańcuch. W takim razie, po co zawracamy sobie głowę tymi całymi grawisami? Mimo że ostateczna wartość jest taka sama, składnia łańcuchów szablonowych pozwala nam wykorzystać funkcjonalności, które nie są dostępne w klasycznych literałach łańcuchowych.
Wstawianie wyrażeń
To niewątpliwie najbardziej rozpowszechnione zastosowanie łańcuchów szablonowych. Koncepcja jest prosta, zamiast konkatenacji możemy wykorzystać interpolację wyrażenia. Aby to zrobić, należy zastosować następującą składnię ${wyrażenie}
. Jest to rozwiązanie zainspirowane językiem skryptowym bash.
Jak widać wariant z wykorzystaniem łańcuchów szablonowych jest dużo czytelniejszy. Warto zauważyć, że wraz z wzrostem liczby wyrażeń, które chcemy wprowadzić do łańcucha, drugi sposób jeszcze bardziej zyskuje na wartości.
Zanim przejdziemy dalej, warto wykorzystać tę okazję i przypomnieć sobie, czym są wyrażenia w języku JavaScript. Jest to każdy fragment kodu, z którego powstaje wartość. Stąd, do łańcucha szablonowego możemy wprowadzić znacznie więcej niż referencję do zmiennej.
Wieloliniowe łańcuchy szablonowe
Tworzenie wieloliniowych łańcuchów przed ES6 wymagało stosowania rozwiązań, które miały niewiele wspólnego z czytelnością. Do najpopularniejszych sposobów należało wykorzystanie tablic lub konkatenacji.
Stosując łańcuchy szablonowe, wszystko staje się dużo prostsze. Nie musimy stosować żadnej dodatkowej składni. Jedyne, czego nam potrzeba, to wciśnięcie klawisza enter w wybranym miejscu.
Wszystko działa tak intuicyjnie, że nie sposób nabrać podejrzeń. Jak to w JSie (i życiu bywa), trzeba zachować czujność. Chwila nieuwagi, i do naszego łańcucha szablonowego trafiają niepożądane znaki. Są to, przede wszystkim, białe spacje.
Oznaczone łańcuchy szablonowe
Drugi z omawianych dzisiaj literałów, daje programistom znacznie większe pole do popisu. Wszystko za sprawą możliwości zastosowania funkcji oznaczającej, która pozwala nam dowolnie modyfikować końcową wartość naszego łańcucha, przed jego kompilacją. Na pierwszy rzut oka może się to wydawać mało praktyczne, ale wystarczy trochę się zastanowić i możemy znaleźć pełno zastosowań dla tej funkcjonalności.
Funkcja oznaczająca zwykle przyjmuje dwa parametry. Pierwszy z nich to tablica łańcuchów składających się na łańcuch szablonowy. Drugi to tablica wyrażeń przekazanych do łańcucha (z wykorzystaniem składni parametrów rest).
Implementacja funkcji oznaczającej
Mniej abstrakcyjny przykład powinien lepiej zobrazować potencjał oznaczonych łańcuchów szablonowych.
Działanie metody reduce wyjaśnię w drugiej części serii, w międzyczasie odsyłam do DevDocs – array.reduce. Na pewno rzuciło się Wam w oczy pominięcie nawiasów przy wywoływaniu funkcji oznaczającej, pizzaDelivery`Dzień dobry, ...`
. Nie jest to błąd, a wyspecjalizowana składnia odróżniająca funkcje oznaczające od innych funkcji.
Jak widać, zastosowanie funkcji oznaczającej zapewnia dużą elastyczność przy przetwarzaniu łańcuchów. Rozpatrywanie wszystkich praktycznych zastosowań przekracza zakres tematyki tego wpisu, zainteresowanych odsyłam do przykładów wyszczególnionych w Exploring ES6 – Examples of using tagged template literals.
Surowe łańcuchy
ECMAScript 2015 oferuje nam wbudowaną funkcję oznaczającą String.raw
. Dzięki niej ukośnik wsteczny (ang. backslash) nie będzie traktowany jako rozpoczęcie sekwencji ucieczkowej.
Dostęp do nieprzetworzonego łańcucha jest również możliwy z poziomu każdej innej funkcji oznaczającej, wystarczy wykorzystać właściwość .raw
.
Podsumowanie
Jak widać, ECMAScript 2015 przyniosło wiele usprawnień wraz z wprowadzeniem dwóch nowych literałów. Zachęcam do wykorzystywania łańcuchów szablonowych z wstawianymi wyrażeniami, zamiast korzystania z klasycznej konkatenacji łańcuchów. Oznaczone łańcuchy szablonowe oferują wielki potencjał, zwłaszcza w dziedzinie tworzenia DSLi (domain-specific languages). Opanowanie praktycznego zastosowania tego literału wymaga czasu. Warto przyjrzeć się propozycjom zaproponowanym przez autorów materiałów źródłowych.
Zachęcam do śledzenia bloga na facebooku. Ponadto jestem dumnym posiadaczem lekko zakurzonego Twittera i raczkującego profilu na LinkedIn.
W przyszłym tygodniu omówię jedną z kluczowych funkcjonalności ECMAScript 2015. Mam tu na myśli destrukturyzację.
Zadania praktyczne
- ES6 Katas (Zadanie 1, 2, 3 i 4)
- ES6 Sandbox (2 zadania)
Każdy z odnośników prowadzi do edytora online z treścią zadania i przygotowanym środowiskiem. Na pewno nie chcesz, aby czas poświęcony na przeczytanie tego wpisu poszedł na marne. Najlepszym sposobem na utrwalanie wiedzy jest praktyka.
Źródła
- Exploring ES6, Template Literals – Dr Axel Rauschmayer
- Understanding ES6, Template Literals – Nicholas C. Zakas
- YDKJS: ES6 & Beyond, Template Literals
– Kyle Simpson - Template Literals are Strictly Better Strings – Nicolás Bevacqua
Zdjęcie tytułowe autorstwa: