Crockford zrobił wiele, aby spopularyzować dobre techniki JavaScript. Jego opinie na temat kluczowych elementów języka wywołały wiele przydatnych dyskusji. To powiedziawszy, jest zdecydowanie zbyt wielu ludzi, którzy traktują każde głoszenie „złego” lub „szkodliwego” jako ewangelii, odmawiając spojrzenia poza opinię jednego człowieka. Czasami może to być trochę frustrujące.
Korzystanie z funkcji new
słowa kluczowego ma kilka zalet w porównaniu z budowaniem każdego obiektu od zera:
- Dziedziczenie prototypów . Choć często przywoływana jest przez podejrzliwość i szyderstwa osób przyzwyczajonych do klasowych języków OO, natywna technika dziedziczenia JavaScript jest prostym i zaskakująco skutecznym sposobem ponownego wykorzystania kodu. Nowe słowo kluczowe to kanoniczny (i dostępny tylko na różnych platformach) sposób jego użycia.
- Wydajność. Jest to efekt uboczny nr 1: jeśli chcę dodać 10 metod do każdego obiektu, który tworzę, mógłbym po prostu napisać funkcję tworzenia, która ręcznie przypisuje każdą metodę do każdego nowego obiektu ... Lub mógłbym przypisać je do właściwości funkcje tworzenia
prototype
i używać new
do wybijania nowych obiektów. Jest to nie tylko szybsze (nie wymaga kodu dla każdej metody w prototypie), ale również pozwala uniknąć balonowania każdego obiektu z osobnymi właściwościami dla każdej metody. W przypadku wolniejszych maszyn (a zwłaszcza wolniejszych interpreterów JS), gdy tworzonych jest wiele obiektów, może to oznaczać znaczne oszczędności czasu i pamięci.
I tak, new
ma jedną istotną wadę, dobrze opisaną innymi odpowiedziami: jeśli zapomnisz go użyć, Twój kod złamie się bez ostrzeżenia. Na szczęście tę wadę można łatwo złagodzić - wystarczy dodać trochę kodu do samej funkcji:
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
Teraz możesz korzystać z zalet, new
nie martwiąc się o problemy spowodowane przypadkowym niewłaściwym użyciem. Możesz nawet dodać twierdzenie do czeku, jeśli przeszkadza ci myśl o uszkodzonym kodzie cicho działającym. Lub, jak niektórzy komentowali, użyj zaznaczenia, aby wprowadzić wyjątek czasu wykonywania:
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Pamiętaj, że ten fragment kodu pozwala uniknąć zakodowania na stałe nazwy funkcji konstruktora, ponieważ w przeciwieństwie do poprzedniego przykładu nie ma potrzeby rzeczywistego tworzenia instancji obiektu - dlatego można go skopiować do każdej funkcji docelowej bez modyfikacji.)
John Resig szczegółowo omawia tę technikę w swoim prostym poście „Tworzenie klasy” , a także domyślnie włącza sposoby budowania tego zachowania w „klasach”. Na pewno warto przeczytać ... jak jego zbliżający się książka Tajemnice JavaScript Ninja , który odnajduje ukryte złoto w tej i wielu innych „szkodliwe” cech języka JavaScript (the rozdział na with
szczególnie oświecania dla tych z nas, którzy początkowo odrzucona ta bardzo złośliwa funkcja jako chwyt).