W jQuery podstawowe wytyczne Style wskazują na dwa różne sposoby, aby sprawdzić, czy zmienna jest zdefiniowana.
- Zmienne globalne:
typeof variable === "undefined"
- Zmienne lokalne:
variable === undefined
- Nieruchomości:
object.prop === undefined
Dlaczego jQuery używa jednego podejścia do zmiennych globalnych, a drugiego do zmiennych lokalnych i właściwości?
javascript
jquery
undefined
Patrick McElhaney
źródło
źródło
foo === undefined
sprawdza lokalną kopię niezdefiniowanej zamiast globalnej (window.undefined), która mogła zostać zmodyfikowana przez szalony kod. Fakt, że niezdefiniowany jest zmienny, jest zdecydowanie wart uwagi i cieszę się, że tak. (+1)Odpowiedzi:
W przypadku niezadeklarowanych zmiennych
typeof foo
zwróci literał ciągu"undefined"
, natomiast sprawdzenie tożsamościfoo === undefined
spowoduje błąd „nie zdefiniowano foo” .Dla zmiennych lokalnych (które znają deklarowane są gdzieś), nie ma takiego błędu mogą się pojawić, stąd sprawdzenie tożsamości.
źródło
typeof foo; // -> "undefined"
), aby podkreślić, że jest to ciąg znaków, a nie pierwotna wartośćundefined
.Chciałbym używać
typeof foo === "undefined"
wszędzie. To nigdy nie może pójść źle.Wyobrażam sobie, że powodem, dla którego jQuery zaleca dwie różne metody, jest to, że definiują one swoją własną
undefined
zmienną w funkcji, w której żyje kod jQuery, więc wewnątrz tej funkcjiundefined
można bezpiecznie manipulować z zewnątrz. Wyobrażam sobie również, że ktoś gdzieś porównał dwa różne podejścia i odkrył, żefoo === undefined
jest to szybsze, i dlatego postanowił, że tak należy. [AKTUALIZACJA: jak zauważono w komentarzach, porównanie zundefined
jest również nieco krótsze, co może być rozważeniem.] Jednak zysk w praktycznych sytuacjach będzie zupełnie nieistotny: ta kontrola nigdy nie będzie nigdy żadnym wąskim gardłem i co utrata jest znacząca: ocena właściwości obiektu hosta do porównania może spowodować błąd, podczas gdy atypeof
sprawdź nigdy nie będzie.Na przykład w IE do analizowania XML używane są:
Aby sprawdzić, czy
loadXML
metoda ma bezpiecznie:Z drugiej strony:
AKTUALIZACJA
Kolejną zaletą
typeof
czeku, o którym zapomniałem wspomnieć, jest to, że działa on również z niezadeklarowanymi zmiennymi, czegofoo === undefined
nie sprawdza i faktycznie rzucaReferenceError
. Dzięki @LinusKleen za przypomnienie. Na przykład:Konkluzja: zawsze używaj
typeof
czeku.źródło
foo === undefined
, po zminimalizowaniu, jest prawdopodobnie czymś podobnymf===u
, podczas gdytypeof foo === "undefined"
można go jedynie zredukować dotypeof f==="undefined"
.var u = "undefined"
i zredukować dotypeof f==u
, co poprawia sytuację, ale wciąż jest większe.typeof
przed niezadeklarowanymi zmiennymi jest zaletą. Jeśli cokolwiek, pozwala to na łatwiejsze pomijanie literówek i nie widzę, kiedy naprawdę chcesz sprawdzić typ niezadeklarowanych zmiennych.Jeszcze jeden powód korzystania z wariantu typeof:
undefined
można zdefiniować na nowo.Wynik
typeof variable
nie może.Aktualizacja : pamiętaj, że nie ma to miejsca w ES5, ponieważ globalny
undefined
jest właściwością, której nie można konfigurować i nie można zapisywać:Ale nadal może być przesłaniany przez zmienną lokalną:
lub parametr:
źródło
undefined
właściwości nie można przedefiniować w ES5, ale nadal można ją zacieniać zmienną lokalną.void 0
jest krótszy i bezpieczniejszy.Ponieważ
undefined
nie zawsze jest deklarowane, ale jQuery deklarujeundefined
w swojej głównej funkcji. Dlatego używają bezpiecznejundefined
wartości wewnętrznie, ale na zewnątrz używajątypeof
stylu, aby być bezpiecznym.źródło
Kto jest zainteresowany wzrostem wydajności
variable === undefined
, może zajrzeć tutaj, ale wydaje się, że jest to tylko optymalizacja chrome.źródło
W przypadku zmiennych lokalnych sprawdzanie za pomocą
localVar === undefined
będzie działać, ponieważ muszą zostać zdefiniowane gdzieś w zasięgu lokalnym lub nie będą uważane za lokalne.W przypadku zmiennych, które nie są lokalne i nie są nigdzie zdefiniowane, sprawdzanie
someVar === undefined
spowoduje zgłoszenie wyjątku: Uncaught ReferenceError: j nie jest zdefiniowanyOto kod, który wyjaśni to, co mówię powyżej. Proszę zwrócić uwagę na wbudowane komentarze dla dalszej przejrzystości .
Jeśli wywołamy powyższy kod w ten sposób:
Wynik byłby następujący:
Jeśli wywołamy powyższy kod w ten sposób (z dowolną wartością):
Dane wyjściowe będą:
Kiedy wykonujesz sprawdzenie w ten sposób:
typeof x === 'undefined'
zasadniczo pytasz: Sprawdź, czy zmiennax
istnieje (została zdefiniowana) gdzieś w kodzie źródłowym. (mniej więcej). Jeśli znasz język C # lub Java, ten typ sprawdzania nigdy nie jest wykonywany, ponieważ jeśli nie istnieje, nie zostanie skompilowany.<== Fiddle Me ==>
źródło
Podsumowanie:
Gdy w zakresie globalnym rzeczywiście chcemy zwrócić wartość true, jeśli zmienna nie jest zadeklarowana lub ma wartość
undefined
:Ponieważ w zakresie globalnym nie jesteśmy w 100% pewni, że deklaracja zmiennej może dać nam błąd referencyjny. Kiedy używamy
typeof
operatora nieznanej zmiennej, nie pojawia się ten problem, gdy zmienna nie jest zadeklarowana:Wynika to z faktu, że
typeof
operator zwraca łańcuch,undefined
gdy zmienna nie jest zadeklarowana lub aktualnie przechowuje wartośćundefined
dokładnie taką, jakiej chcemy.undefined
źródło
typeof a === 'undefined'
jest szybszy niża === 'undefined'
około 2 razy w węźle v6.9.1.źródło
undefined
drugą część, a nie'undefined'