…a dokładniej to mowa o ECMAScript 5 i jednej z ważniejszych nowości, które wprowadza do ulubionego języka programistów :-) Mowa oczywiście o trybie ścisłym (ang. Strict Mode). Czym jest owy tryb i dlaczego warto go używać, a także kiedy nie używać?
Tryb ścisły, jak mówi sama nazwa, jest ograniczonym wariantem języka JavaScript. Oznacza to, że w trybie ścisłym celowo zostało usuniętych kilka „złych” funkcjonalności/praktyk pisania kodu, tak by móc jak najwcześniej wykrywać i lokalizować błędy, a sam kod był lepszej jakości, co umożliwi przeglądarkom dokonywanie optymalizacji.
Tryb ścisły to również zmieniona semantyka tworzenia kodu, więc przeglądarki bez wsparcia dla Strict Mode będą wykonywały kod JavaScript w inny sposób (należy mieć to na uwadze, gdyż może doprowadzić do błędów wykonania kodu).
Przejście do Strict Mode
Sposób oznaczania kodu JavaScript do uruchomiania w trybie ścisłym jest rozwiązany:
- nieinwazyjnie – nie spowoduje błędów w przeglądarkach, które go nie wspierają,
- banalnie prosto – wystarczy dodać jedną linijkę kodu.
Tryb ścisły można włączyć globalnie, dla całego kodu lub lokalnie, dla wybranych funkcji. Można również aktywować tryb ścisły dla kodu wykonywanego w funkcji eval czy setTimeout.
Aby przejść do Strict Mode wystarczy dodać na początku kodu:
1 2 | "use strict"; // your code... |
Czy też dla funkcji:
1 2 3 4 | function a() { "use strict"; // your code... }; |
Jak więc widzisz, dodajemy do kodu zwykły string o specjalnej wartości. Wartość ta jest jasna dla przeglądarek z zaimplementowanym trybem ścisłym – pozostałe oleją ten kawałek kodu.
Jakie zmiany wprowadza tryb ścisły?
Tryb ścisły ma za zadanie pomagać w trzech wariantach:
- uniemożliwia stosowanie przestarzałych składni języka – rzuca w przypadku ich stosowania błędami,
- pomyłki traktuje jako błędy, byś mógł je możliwie szybko wykrywać i naprawiać,
- uniemożliwia stosowania składni zarezerwowanej do zaimplementowania w kolejnych wydaniach ECMAScriptu, aby w przyszłości nasz kod nadal wykonywał się poprawnie.
Powyższa lista nie przekazuje za wiele konkretów, dlatego wymieńmy najistotniejsze zmiany bardziej szczegółowo:
- Przypadkowe zmienne globalne są traktowane jako błąd. W domyślnym trybie możesz definiować w dowolnym miejscu funkcji zmienne globalne – wystarczy pominąć var. To może powodować błędy, które zazwyczaj są bardzo ciężkie do wykrycia, np.
1
2
3
4
5"use strict";
for (i = 0; i < length; i++) { // TypeError
// some code...
};W tym momencie zdefiniowaliśmy zmienną globalną i, co niekoniecznie jest dobrym rozwiązaniem, skoro to zmienna na potrzeby tylko jednej pętli.
Innym popularny błędem są literówki, np.
1
2
3
4
5
6
7"use strict";
var userName = '';
function setUserName(name) {
user_name = name; // TypeError
}; - Próba nadpisania nienadpisywalnych obiektów globalnych to błąd. Dotychczas przy próbie nadpisania wartości zmiennych globalnych typu NaN czy Infinity nie wyskakiwał żaden błąd, ale też przeglądarka nie przypisywała im wartości, które chcemy. W trybie ścisłym zostanie wyrzucony wyjątek TypeError.
1
2
3
4"use strict";
NaN = 3; // TypeError
Infinity = 3; // TypeError - Próba usunięcia nieusuwalnej własności to błąd. Wcześniej taka próba spełzła na niczym, lecz nie było też informacji o błędzie. Teraz to się zmieni i pojawi się stosowny wyjątek, np.
1
2
3
4
5
6
7
8
9"use strict";
delete Object.prototype; // TypeError
var a = 3;
delete a; // TypeError
function b() {}
delete b; // TypeError - Niedozwolone jest stosowanie składni ósemkowej. W domyślnym trybie wszystkie liczby poprzedzone zerem były traktowane jako liczby w systemie ósemkowym (co niekoniecznie mogło być celowe i doprowadzało do błędów).
1
2
3"use strict";
var sum = 030 + 113 + 450; // SyntaxError - Duplikujące się nazwy własności w obiektach to błąd. W normalnym trybie kolejne własności o powtarzającej się nazwie nadpisywałby wartość dla danej własności, w trybie ścisłym taki zapis jest błędem składniowym.
1
2
3"use strict";
var o = {'a': 1, 'b': 2, 'a': 3} // SyntaxError - Argumenty w funkcjach muszą mieć unikalne nazwy. Podobnie jak z obiektami, powtarzalne nazwy argumentów nadpisywałyby wartości, nie informując o błędach. Na szczęście w trybie ścisłym zostaniesz dostatecznie szybko poinformowany o kodzie, który wcześniej czy później spowodowałby błąd.
1
2
3
4
5"use strict";
function concat(a, b, a) { // SyntaxError
return '' + a + b + a;
} - Niedozwolone jest korzystanie ze składni with. Używanie with jest od dawna niezalecane ze względów wydajnościowych, natomiast w trybie ścisłym całkowicie zabronione.
1
2
3
4
5
6"use strict";
with (objectA.objectB.objectC.objectD.objectE) { // SyntaxError
a = true;
b = false;
}Korzystanie z with upraszcza kod, lecz alternatywnie można użyć równie prostej (i dużo bardziej wydajnej) składni:
1
2
3var o = objectA.objectB.objectC.objectD.objectE;
o.a = true;
o.b = false; - Kod wykonany w eval w trybie ścisłym nie wprowadza nowych zmiennych do kodu. Niemożliwe jest również modyfikowanie „zewnętrznych” zmiennych:
1
2
3
4
5
6"use strict";
var x = 1;
eval('x = 3;');
x; // 1czy jednoznaczne do powyższego:
1
2
3
4var x = 1;
eval('"use strict"; x = 3;');
x; // 1 - Zabronione jest nadpisywanie eval oraz arguments. W domyślnym trybie możliwe było nadpisanie funkcji eval czy obiektu arguments, co w skutku mogło doprowadzić do dziwacznych błędów.
W trybie ścisłym poniższe kody zakończą się błędami składni:
1
2
3
4
5
6"use strict";
function toArray() {
arguments = 3; // SyntaxError
return arguments;
}1
2
3"use strict";
eval = ''; // SyntaxErrorPrzy okazji obiektu arguments, jeszcze dwie nowinki:
- Właściwości obiektu arguments nie są alisowane. A to oznacza, że w obiekcie arguments zawsze będą znajdować się domyślnie przekazane zmienne do funkcji.
Wcześniej więc mieliśmy sytuacje:
1
2
3
4
5
6function abc(a) {
a = 2;
return arguments;
}
abc(1, 2, 3); // [2, 2, 3]W trybie ścisłym ten sam kod będzie wyglądał następująco:
1
2
3
4
5
6
7
8"use strict";
function abc(a) {
a = 2;
return arguments;
}
abc(1, 2, 3); // [1, 2, 3] - Dodano nowe słowa zarezerwowane. To słowa, które mogą zostać użyte jako składnia w kolejnych wydaniach ECMAScriptu (nawiasem mówiąc, część z nich jest już w użyciu). Do słów takich można zaliczyć m. in.: implements, interface, let, package, private, protected, public, static i yield.
- Brak wsparcia dla arguments.callee.
Wsparcie dla Strict Mode w przeglądarkach
Tryb ścisły języka JavaScript jest obecnie obsługiwany przez wszystkie nowoczesne przeglądarki, tj. Firefox, Chrome, Opera, a nawet IE10. Również zadziała z mobilnymi przeglądarkami, tj. iOS Safari, Android Browser czy Blackberry Browser. Nie zadziała natomiast ze starszymi wersjami Internet Explorera oraz Operą Mini.
Co się stanie, jeśli Twoje skrypty są dostosowana do trybu ścisłego, a przeglądarka go nie obsługuje? Teoretycznie nic – jeśli Twój kod jest napisany prawidłowo to zostanie wykonany bezbłędnie.
Kiedy zatem nie używać trybu ścisłego? Kiedy Twój kod jest brzydki, przestarzały i „śmierdzi” (jakby to powiedział Robert C. Martin, autor książki „Clean Code”, którą przy okazji polecam!).
Strict Mode to świetne ułatwienie ze strony twórców przeglądarek dla każdego programisty – pomaga wykrywać problemy możliwie szybko, optymalizuje kod, a także przystosowuje go do działania razem z przyszłymi wersjami ECMAScriptu. Podsumowując, jak najbardziej powinieneś używać trybu ścisłego już dzisiaj! :-)
Dzięki za info! Przydatne informacje jak zawsze.
[…] Tryb ścisły, jak mówi sama nazwa, jest ograniczonym wariantem języka JavaScript. […]