JavaScript sprawdź, czy zmienna istnieje (jest zdefiniowana / zainicjowana)


1762

Która metoda sprawdzania, czy zmienna została zainicjowana, jest lepsza / poprawna? (Zakładając, że zmienna może pomieścić wszystko (łańcuch, int, obiekt, funkcja itp.))

if (elem) { // or !elem

lub

if (typeof(elem) !== 'undefined') {

lub

if (elem != null) {

5
jeśli chcesz wiedzieć, czy foojest zadeklarowany, albo typeof foo === 'undefined'albotypeof foo === typeof undefined

1
Wysoko ocenione odpowiedzi nie działają w przypadku zadeklarowanych zmiennych, ale mają wartość undefined. Prawidłowa odpowiedź to: stackoverflow.com/a/36432729/772035
Paul

@Paulpro wersja korzystania hasOwnProperty('bar')nie mają te same braki, jak inni, ale wymaga pewnych korekt dla węzła (wymienić windowz global).
oligofren

@Paulpro Rzeczywiście, ale zastanawiając się nad tym, zanim odpowiedziałeś, doszedłem do wniosku, że to nie jest tak naprawdę praktyczny problem. Kiedy masz do czynienia ze zmiennymi o zasięgu blokowym lub funkcyjnym, zwykle jest to kod, do którego jesteś właścicielem lub masz dostęp do zapisu, więc w każdym przypadku wystąpi błąd w czasie wykonywania, który można naprawić. Podczas gdy zwykły problem ze zmiennymi, które nie zostały zdefiniowane (nie istnieją), zwykle leży w kodzie poza twoją kontrolą, więc potrzebujesz sposobu na ich wykrycie. To rozwiązanie 80/20.
oligofren

Odpowiedzi:


3051

Chcesz się z typeofoperatorem . Konkretnie:

if (typeof variable !== 'undefined') {
    // the variable is defined
}

35
To wygląda na dobre rozwiązanie, ale czy możesz wyjaśnić, dlaczego to działa?
Morgan Cheng

46
Właściwie powinieneś sprawdzić, czy obiekt jest tym, czego potrzebujesz. Tak by było, gdyby (typeof console == 'object') {// zmienna jest tym, czego potrzebuję}
staticsan

59
@George IV: „po prostu zrób„ jeśli (zmienna) ”- um, nie, to nie powiedzie się dla fałszu i 0.
Jason S

17
„if (zmienna)” również nie sprawdza się pod kątem istnienia właściwości obiektu.
scotts

54
@ geowa4 Właściwie, spowoduje to błąd, jeśli zmienna jest niezdefiniowana.
kevinji,

856

typeofOperator sprawdzi, czy zmienna jest naprawdę niezdefiniowane.

if (typeof variable === 'undefined') {
    // variable is undefined
}

typeofOperator, w przeciwieństwie do innych operatorów, nie rzucać ReferenceError wyjątku w przypadku korzystania z zmiennej nierejestrowanej.

Pamiętaj jednak, że typeof nullwróci "object". Musimy uważać, aby uniknąć błędu inicjalizacji zmiennej null. Aby być bezpiecznym, możemy zamiast tego użyć:

if (typeof variable === 'undefined' || variable === null) {
    // variable is undefined or null
}

Aby uzyskać więcej informacji na temat używania ścisłego porównania ===zamiast prostej równości ==, zobacz:
Który operator równości (== vs ===) powinien być używany w porównaniach JavaScript?


2
if (! variable_here) {// twój kod tutaj. }; nie mogę powiedzieć, czy zmienna jest fałszywa czy niezdefiniowana
boh 17'13

5
if(! variable_here)pęknie w wielu przypadkach. Jeśli zmienna ma wartość 0 lub false, nie powiedzie się. Nie tego chcesz.
Cory Danielson

2
nie mogę zdecydować, czy głosować w górę. Ściśle mówiąc, typeof foo === "undefined"jest poprawna i lepsza niż najlepsza głosowana odpowiedź, ale dodatkowe uwagi tylko niejasną.
Alnitak

1
@StevenPenny Sprawdź oś czasu. Najlepsza odpowiedź została połączona z innym pytaniem po opublikowaniu tej odpowiedzi
Rob

1
Ta odpowiedź nie działa. To jest jedyna odpowiedź, która działa: stackoverflow.com/a/36432729/772035
Paul

222

W wielu przypadkach użycie:

if (elem) { // or !elem

zrobi to za Ciebie! ... sprawdzi następujące poniższe przypadki:

  1. undefined : jeśli wartość nie jest zdefiniowana i jestundefined
  2. null : jeśli jest pusty, na przykład jeśli element DOM nie istnieje ...
  3. pusty ciąg :''
  4. 0 : liczba zero
  5. NaN : brak liczby
  6. fałszywe

Będzie więc obejmował wszystkie przypadki, ale zawsze są dziwne przypadki, które chcielibyśmy również uwzględnić, na przykład ciąg znaków ze spacjami, taki jak ten ' ', zostanie zdefiniowany w javascript, ponieważ ma spacje wewnątrz ciągu ... na przykład w tym przypadku dodajesz jeszcze jedną kontrolę za pomocą trim (), na przykład:

if(elem) {

if(typeof elem === 'string' && elem.trim()) {
///

Ponadto te kontrole dotyczą tylko wartości , ponieważ obiekty i tablice działają inaczej w JavaScript, pusta tablica []i pusty obiekt {}są zawsze prawdziwe .

Tworzę obraz poniżej, aby pokazać krótki skrót odpowiedzi:

niezdefiniowany, zerowy itp


2
@Alireza, miło! Twoja odpowiedź pomoże wielu ludziom. Zapamiętałem już te wartości fałszowania, jedyne, o czym nie byłem pewien [].
Thiago Yoithi,

13
Dostaję komunikat „ReferenceError: elem nie jest zdefiniowany”
ropo,

3
@ropo, to dlatego, że nawet nie zdefiniowałeś elementu, aby sprawdzić, co to jest, jeśli to twoja sprawa, musisz to sprawdzić za pomocą typeof (elem) === „ciąg”, który jest już wspomniany ...
Alireza

19
Zatem odpowiedź jest myląca, gdy mówi, że if(elem)sprawdza , czy nie jest zdefiniowany (chociaż zwraca nieokreślony błąd), prawda?
Fanky

1
Daj mi przypadek użycia do sprawdzenia, czy zmienna jest niezdefiniowana i czy jest zdefiniowana z niezdefiniowaną wartością? Niektórzy z was chwytają się słomek i próbują wyglądać genialnie, ale jeśli ustawiacie wartość jako niezdefiniowaną i sprawdzacie tę wartość, to oczywiście zwróci ona fałsz lub trzeba zmienić kod, smh .... ta odpowiedź jest poprawna !! !!!
almcaffee,

210

W JavaScript można zdefiniować zmienną, ale zachować tę wartość undefined, więc najczęstsza odpowiedź nie jest technicznie poprawna i zamiast tego wykonuje następujące czynności:

if (typeof v === "undefined") {
   // no variable "v" is defined in the current scope
   // *or* some variable v exists and has been assigned the value undefined
} else {
   // some variable (global or local) "v" is defined in the current scope
   // *and* it contains a value other than undefined
}

To może wystarczyć do twoich celów. Poniższy test ma prostszą semantykę, co ułatwia precyzyjne opisanie zachowania twojego kodu i zrozumienie go samemu (jeśli zależy Ci na takich rzeczach):

if ("v" in window) {
   // global variable v is defined
} else {
   // global variable v is not defined
}

To oczywiście zakłada, że ​​działasz w przeglądarce (gdzie windowjest nazwa obiektu globalnego). Ale jeśli bawisz się takimi globalami, prawdopodobnie jesteś w przeglądarce. Subiektywnie używanie 'name' in windowjest stylistycznie spójne z używaniem window.namew odniesieniu do globali. Dostęp do globałów jako właściwości windowzmiennych zamiast jako zmiennych pozwala zminimalizować liczbę niezadeklarowanych zmiennych, do których się odwołujesz w kodzie (na korzyść puchnięcia), i pozwala uniknąć cieniowania globalnej zmiennej lokalnej. Ponadto, jeśli globale powodują, że skóra się czołga, możesz czuć się bardziej komfortowo dotykając ich tylko tym stosunkowo długim kijem.


7
Sprawdza to tylko, czy zmienna została zadeklarowana globalnie. Jeśli prawidłowo kodujesz, to ograniczasz swoje globalne różnice. Zgłasza fałsz dla lokalnych zmiennych: (function () {var sdfsfs = 10; console.log ("sdfsfs" w oknie);}) () `
Eddie Monge Jr

2
To najlepsza odpowiedź na pytanie. Byłem u kresu rozumu, próbując wymyślić, jak wytłumaczyć dokładnie tę narożną sprawę. Znakomity. Nie miałem pojęcia, że ​​możesz to zrobić.
tymczasowego

1
Heads-up: Twoja odpowiedź została przeniesiona tutaj z stackoverflow.com/questions/519145/...
Shog9

Dla użytkowników Angular: Niestety, wydaje się, że nie jest to dozwolone w instrukcji ng-if.
qwertzguy,

... idealny plan dla kontroli wzdłuż zasięgu. masz jakieś wskazanie wydajności, jeśli „w oknie” lub „(typeof zmienna ===„ niezdefiniowana ”|| zmienna === null)”. Właściwie interesuje mnie trudny test faktów, a nie argumentacja potencjalnego uzasadnienia (co mogłabym zrobić sama: druga klauzula ma więcej operacji -> gorsza wydajność)
Quicker

119

W większości przypadków użyłbyś:

elem != null

W przeciwieństwie do proste if (elem), umożliwia 0, false, NaNi '', lecz odrzuca nulllub undefined, co bardzo dobry, ogólny test na obecność argument lub właściwości obiektu.


Inne kontrole również nie są niepoprawne, mają tylko różne zastosowania:

  • if (elem): Mogą być stosowane, jeżeli elemjest gwarancją obiektu, lub jeśli false, 0itd są uważane za wartości „domyślne” (stąd równoważne undefinedlub null).

  • typeof elem == 'undefined'może być stosowany w przypadkach, gdy określony nullma odrębne znaczenie dla niezainicjowanej zmiennej lub właściwości.

    • Jest to jedyna kontrola, która nie zgłosi błędu, jeśli elemnie zostanie zadeklarowana (tj. Brak varinstrukcji, brak właściwości windowlub argument funkcji). Jest to, moim zdaniem, dość niebezpieczne, ponieważ pozwala na pomijanie literówek. Aby tego uniknąć, zobacz poniższą metodę.

Przydatne jest również ścisłe porównanie z undefined:

if (elem === undefined) ...

Ponieważ jednak globalny undefinedmożna zastąpić inną wartością, undefinedprzed użyciem należy zadeklarować zmienną w bieżącym zakresie:

var undefined; // really undefined
if (elem === undefined) ...

Lub:

(function (undefined) {
    if (elem === undefined) ...
})();

Druga zaleta tej metody polega na tym, że minizatory JS mogą zredukować undefinedzmienną do jednego znaku, oszczędzając za każdym razem kilka bajtów.


17
Jestem zszokowany, że możesz to zmienić undefined. Nie sądzę, że warto o tym wspomnieć w odpowiedzi. Prawdopodobnie najgorsza akceptowalna nazwa zmiennej w całym Javascript.
Cory Danielson

2
Powoduje to wyjątek i wymaga użycia window.przed zmienną, jeśli jest używana w kontekście globalnym ... nie jest to najlepszy sposób.
Alex W

4
Z powodu tego nadrzędnego problemu powinieneś ZAWSZE używać void(0)zamiast undefined.
Bartłomiej Zalewski

+1 ponieważ owa odpowiedź zaznacza, że czasami może rzeczywiście chcą zidentyfikować false, 0itp jako nieprawidłowych wartości.
rinogo

77

Sprawdź, czy window. hasOwnProperty( varname )

Alternatywa dla mnóstwa typeofodpowiedzi;

Zmienne globalne zadeklarowane za pomocą var varname = value;instrukcji w zakresie globalnym

mogą być dostępne jako właściwości obiektu okna.

Jako taka hasOwnProperty()metoda, która

zwraca wartość logiczną wskazującą, czy obiekt ma określoną właściwość jako swoją własność (w przeciwieństwie do dziedziczenia)

można użyć do ustalenia, czy

a varnazwy „varname” zostało zadeklarowane globalnie, tj. jest własnością window.

// Globally established, therefore, properties of window
var foo = "whatever", // string
    bar = false,      // bool
    baz;              // undefined
//  window.qux does not exist

console.log( [
    window.hasOwnProperty( "foo" ), // true
    window.hasOwnProperty( "bar" ), // true
    window.hasOwnProperty( "baz" ), // true
    window.hasOwnProperty( "qux" )  // false
] );

Wspaniałe hasOwnProperty()jest to, że nazywając go, nie używamy zmiennej, która może być jeszcze niezadeklarowana - co oczywiście stanowi połowę problemu.

Chociaż nie zawsze jest to idealne lub idealne rozwiązanie, w pewnych okolicznościach jest to po prostu praca!

Notatki

Powyższe jest prawdziwe w przypadku używania vardo definiowania zmiennej , w przeciwieństwie do let:

deklaruje zmienną lokalną o zasięgu bloku, opcjonalnie inicjując ją do wartości.

różni się od varsłowa kluczowego, które definiuje zmienną globalnie lub lokalnie dla całej funkcji, niezależnie od zasięgu bloku.

Na najwyższym poziomie programów i funkcji, letw przeciwieństwie do tego var, nie tworzy właściwości na obiekcie globalnym.

Dla kompletności: const stałe z definicji nie są w rzeczywistości zmienne (chociaż ich treść może być); bardziej odpowiednio:

Stałe globalne nie stają się właściwościami obiektu okna, w przeciwieństwie do varzmiennych. Wymagany jest inicjator stałej; to znaczy, musisz podać jego wartość w tej samej instrukcji, w której jest zadeklarowana.

Wartość stałej nie może się zmienić poprzez zmianę przypisania i nie można jej ponownie zadeklarować.

Deklaracja const tworzy odwołanie do wartości tylko do odczytu. Nie oznacza to, że wartość, którą posiada, jest niezmienna, po prostu nie można przypisać identyfikatora zmiennej.

Ponieważ letzmienne lub conststałe nigdy nie są właściwościami żadnego obiektu, który odziedziczył hasOwnProperty()metodę, nie można go użyć do sprawdzenia ich istnienia.

W odniesieniu do dostępności i wykorzystania hasOwnProperty():

Każdy obiekt pochodzący od Object dziedziczy hasOwnProperty()metodę. [...] w przeciwieństwie do inoperatora, ta metoda nie sprawdza łańcucha prototypów obiektu.


1
To niesamowita alternatywa i powinna być na szczycie tego pytania. Proszę uprościć nagłówek odpowiedzi za pomocą działającego przykładu, który zwraca true(np. window.hasOwnProperty('console')Lub var hop = "p";window.hasOwnProperty('hop')).
CPHPython

2
Wreszcie coś, co nie powoduje błędu z powodu dostępu do członka, który nie istnieje… Coś, co wszystkie typeofodpowiedzi po prostu przeoczają.
Zelphir Kaltstahl

1
Ta odpowiedź jest nieaktualna - w standardowym skrypcie ECMAScript można zdefiniować zmienne, w letktórych zmienne te nie są dostępne jako właściwości window[lub innego dostępnego] obiektu. hasOwnPropertytesty na obecność właściwości , a nie zmiennych, a zatem nie mogą być używane do wykrywania zmiennych zdefiniowanych przez let.
am

1
@amn Odpowiedź pozostaje prawdziwa w odniesieniu do użycia vari jest w tym względzie nieaktualna. Dodałem jednak notatkę opisującą, w jaki sposób użycie leti constróżni się od var. Dzięki za inspirację; razem powstajemy :)
Fred Gandt

1
@am Napisałem odpowiedź (mam nadzieję, że po raz ostatni), aby wyjaśnić, że hasOwnPropertymożna jej użyć tylko w określony sposób, aby sprawdzić istnienie varzmiennych. Dla mnie to brzmi dobrze.
Fred Gandt

68

Jak sprawdzić, czy zmienna istnieje

Jest to dość kuloodporne rozwiązanie do testowania, czy zmienna istnieje i została zainicjowana:

var setOrNot = typeof variable !== typeof undefined;

Najczęściej jest używany w połączeniu z operatorem trójskładnikowym, aby ustawić wartość domyślną w przypadku, gdy pewna zmienna nie została zainicjowana:

var dark = typeof darkColor !== typeof undefined ? darkColor : "black";

Problemy z enkapsulacją

Niestety nie można po prostu zawrzeć czeku w funkcji.

Możesz pomyśleć o zrobieniu czegoś takiego:

function isset(variable) {
    return typeof variable !== typeof undefined;
}

To jednak spowoduje błąd odniesienia, jeśli dzwonisz np. isset(foo)i zmienna foonie została zdefiniowana, ponieważ nie można przekazać nieistniejącej zmiennej do funkcji:

Uncaught ReferenceError: foo nie jest zdefiniowane


Testowanie, czy parametry funkcji są niezdefiniowane

Chociaż nasza issetfunkcja nie może być używana do testowania, czy zmienna istnieje, czy nie (z powodów wyjaśnionych powyżej), pozwala nam przetestować, czy parametry funkcji są niezdefiniowane:

var a = '5';

var test = function(x, y) {
    console.log(isset(x));
    console.log(isset(y));
};

test(a);

// OUTPUT :
// ------------
// TRUE
// FALSE

Mimo że ydo funkcji nie jest przekazywana żadna wartość test, nasza issetfunkcja działa idealnie w tym kontekście, ponieważ yjest znana w funkcji testjako undefinedwartość.


41

Istnieje inny krótki sposób sprawdzenia tego, gdy wykonujesz proste zadania i powiązane kontrole. Wystarczy użyć operatora warunkowego (trójskładnikowego).

var values = typeof variable !== 'undefined' ? variable : '';

Będzie to również pomocne, gdy spróbujesz zadeklarować zmienną globalną przy pomocy instancji zmiennej referencyjnej.

Jeśli chcesz sprawdzić zmienną nie powinna być undefinedlub null. Następnie wykonaj poniższe sprawdzenie.

Gdy zmienna jest zadeklarowana, a jeśli chcesz sprawdzić wartość, jest to nawet proste: wykona się undefinedi nullsprawdzi razem.

var values = variable ? variable : '';

odpowiedź jest błędna. zmienna typeof zawsze zwraca ciąg, dlatego nigdy nie jest fałszywa. np. jeśli typeof(booooo)jest "undefined"wtedy typeof(typeof boooooo)jest "string"i typeof boooooo && truejest zawsze true. Odpowiedź Johna-Slegersa jest tak skrócona, jak to tylko możliwe w przypadku typeof.
mpag

To absolutnie poprawna odpowiedź . Oto działający Fiddle . I nie wiem o jakim scenariuszu mówisz. Pytania dotyczą sprawdzenia istnienia zmiennej.
RajeshKdev

@mpag Nie mów źle Flat. Udowodnij to . Znalezienie błędu jest naprawdę łatwe, zamiast tego możesz podać tutaj Dobre odpowiedzi !!!. Jeśli odpowiedź jest błędna, 28 programistów nie głosowałoby bez sprawdzenia mojej odpowiedzi. Ponieważ istnieje tutaj wiele renomowanych odpowiedzi, mogliby głosować na to, nie to.
RajeshKdev

W rzeczywistości drugą częścią kodu nie jest sprawdzenie tego samego, co powyżej. Myślałem, że ludzie zrozumieją z tego wiersza If you wanted to check variable shouldn't be undefined or null.: Przez ten komentarz, wyraźnie stwierdzający, że nie należy przeprowadzać sprawdzania deklaracji zmiennych. to jest sprawdzenie wartości zmiennej.
RajeshKdev

1
twoje drugie sprawdzenie zakończy się niepowodzeniem z wartością 0
Fareed Alnamrouti

32

Krótki sposób testowania zmiennej nie jest zadeklarowany (nie jest niezdefiniowany)

if (typeof variable === "undefined") {
  ...
}

Uznałem, że jest to przydatne do wykrywania skryptu działającego poza przeglądarką (bez deklarowania windowzmiennej).


czy jest to „kanoniczny sposób”, który jest przenośny?
Jason

3
To jest źle. window.bar=undefinedjest zdefiniowany i ustawiony na wartość. Twoja odpowiedź nie wykrywa różnicy między tym a tym, jeśli zmienna nie istnieje. Gdybyś to zrobił this.hasOwnProperty('bar'), mogłoby to zadziałać.
oligofren

ten kod nie działa i możesz to sprawdzić za pomocą dowolnej konsoli przeglądarki
ha9u63ar

1
Zastanów się const x = 0; (() => console.log(x, this.hasOwnProperty('x')))();. Zmienna xjest zdefiniowana, ale zwracana jest wartość false ...
user2878850,

29

To zależy, czy zależy ci tylko na tym, aby zmienna została zdefiniowana, czy na wartości, która ma mieć znaczenie.

Sprawdzenie, czy typ jest niezdefiniowany, sprawdzi, czy zmienna została jeszcze zdefiniowana.

=== nulllub !== nullsprawdzi tylko, czy wartość zmiennej jest dokładnie null.

== nulllub != nullsprawdzi, czy wartość wynosi undefinedlub null.

if(value)sprawdzi, czy zmienna jest undefined, null, 0lub pusty ciąg.


12

Najwyższa odpowiedź jest poprawna, użyj typeof.

Chciałem jednak zauważyć, że w JavaScript undefinedmożna modyfikować (z jakiegoś bezbożnego powodu). Więc po prostu sprawdzenie, czy varName !== undefinednie, może nie zawsze powrócić tak, jak tego oczekujesz, ponieważ inne biblioteki lib mogły ulec zmianie niezdefiniowane. Kilka odpowiedzi (na przykład @ Skalee'a) wydaje się, że wolą nie używać typeof, a to może sprawić kłopoty.

„Starym” sposobem radzenia sobie z tym było zadeklarowanie niezdefiniowanego jako var, aby zrównoważyć wszelkie potencjalne wyciszenie / przekroczenie undefined. Jednak najlepszym sposobem jest nadal używanie, typeofponieważ zignoruje wszelkie zastąpienie undefinedz innego kodu. Zwłaszcza jeśli piszesz kod do wykorzystania na wolności, gdzie kto wie, co jeszcze może być uruchomione na stronie ...


1
Chodzi o kwestię sporną, ponieważ jeśli varName nie jest zdefiniowany varName !== undefined, spowoduje to błąd ReferenceError. Zmienność undefinednie będzie miała znaczenia.
Wutaz

Heads-up: Twoja odpowiedź została przeniesiona tutaj z stackoverflow.com/questions/519145/...
Shog9

1
W nowszych wersjach Javascript undefinedjest właściwością tylko do odczytu. Jednak aby być kuloodpornym, możesz użyć typeof mvVar === typeof void 0. zawsze void 0wraca undefined.
kwarnke

11
if (typeof console != "undefined") {    
   ...
}

Albo lepiej

if ((typeof console == "object") && (typeof console.profile == "function")) {    
   console.profile(f.constructor);    
}

Działa we wszystkich przeglądarkach


3
Dlaczego według ciebie to drugie jest lepsze?
skalee

3
@skalee Zgadzam się, że to drugie jest lepsze. To z prostego powodu, aby sprawdzić, czy typy są tymi, których potrzebujesz przed ich użyciem.
Broxzier,

Heads-up: Twoja odpowiedź została przeniesiona tutaj z stackoverflow.com/questions/519145/...
Shog9

9

Aby wziąć udział w debacie, jeśli wiem, że zmienna powinna być łańcuchem lub obiektem, zawsze wolę if (!variable), więc sprawdzam, czy jest to fałsz. Może to doprowadzić do czystszego kodu, dzięki czemu na przykład:

if (typeof data !== "undefined" && typeof data.url === "undefined") {
    var message = 'Error receiving response';
    if (typeof data.error !== "undefined") {
        message = data.error;
    } else if (typeof data.message !== "undefined") {
        message = data.message;
    }
    alert(message); 
}

.. można zmniejszyć do:

if (data && !data.url) {
  var message = data.error || data.message || 'Error receiving response';
  alert(message)
} 


Nie o to prosił PO. Jeśli data.url jest równe ''twojemu rozwiązaniu, uznałoby to za niezdefiniowane, gdy w rzeczywistości jest zdefiniowane jako zawierające pusty ciąg.
Demonblack

Zgadzam się, że nie o to pytano, a ty masz rację: pusty ciąg znaków „” zostałby uznany za niezdefiniowany. Ale zamieściłem to, ponieważ uważałem, że może być przydatne w debacie, która została stworzona wśród różnych odpowiedzi. I w tym przykładzie, podobnie jak w wielu innych przypadkach, po prostu chcesz wydrukować ciąg znaków, jeśli rzeczywiście jest w nim treść, więc dobrze jest skorzystać z faktu, że javascript uważa, że ​​fałsz jest zarówno pusty, jak i niezdefiniowany
de3

8

Trudno rozróżnić niezdefiniowane od zerowego. Null to wartość, którą można przypisać do zmiennej, jeśli chcesz wskazać, że zmienna nie ma określonej wartości. Niezdefiniowana to specjalna wartość, która będzie domyślną wartością nieprzypisanych zmiennych.


var _undefined;
var _null = null;

alert(_undefined); 
alert(_null); 
alert(_undefined == _null);
alert(_undefined === _null);


1
Byłoby pomocne, aby pokazać wbudowane wyjście każdego ostrzeżenia.
demisx

@demisx Zgoda, ale zamiast sugerować edycję, dlaczego nie zrobić tego? Ta opcja istnieje z jakiegoś powodu. Niektórzy mogą uznać to za niegrzeczne; Uważam to za skuteczne - więc sam zredagowałem odpowiedź (w oczekiwaniu na recenzję).
Fred Gandt,

1
@Fred - Spojrzałem na historię edycji i mogę odgadnąć, dlaczego twoje zmiany zostały odrzucone ... zamiast dodawać wiersze, aby pokazać, jaki byłby wynik, jak sugeruje demisx, znacząco zmieniłeś to, co napisał Jith.
Stephen P

8

Null jest wartością w JavaScript i typeof nullzwraca"object"

Dlatego zaakceptowana odpowiedź nie zadziała, jeśli przekażesz wartości null. Jeśli przekażesz wartości null, musisz dodać dodatkowe sprawdzenie wartości null:

if ((typeof variable !== "undefined") && (variable !== null))  
{
   // the variable is defined and not null
}

7

Najbardziej niezawodna kontrola „jak to zdefiniowano” dotyczy typu typeof

if (typeof elem === 'undefined')

Jeśli po prostu sprawdzasz zdefiniowaną zmienną do przypisania wartości domyślnej, dla łatwego do odczytania jednego linijki często możesz to zrobić:

elem = elem || defaultElem;

Często jest dobrze używać, patrz: Idiomatyczny sposób ustawiania wartości domyślnej w javascript

Istnieje również jedna linijka wykorzystująca słowo kluczowe typeof :

elem = (typeof elem === 'undefined') ? defaultElem : elem;


7

Aby sprawdzić, czy zmienna została zadeklarowana / ustawiona, zrobiłem tę brudną sztuczkę.

Nie znalazłem sposobu na wyodrębnienie kodu do funkcji, nawet przy pomocy eval.

"use strict";

// var someVar;

var declared;
try {
  someVar;
  declared = true;
} catch(e) {
  declared = false;
}

if (declared) {
  console.log("someVar is declared; now has the value: " + someVar);
} else {
  console.log("someVar is not declared");
}

Co rozumiesz przez „wypakuj kod do funkcji”?
Melab

7

Te odpowiedzi (oprócz rozwiązania Freda Gandta) są niepoprawne lub niekompletne.

Załóżmy, że muszę variableName;mieć undefinedwartość, a zatem została zadeklarowana w taki sposób, że var variableName;oznacza to, że została już zainicjowana ; - Jak sprawdzić, czy jest już zadeklarowany?

Albo jeszcze lepiej - jak od razu sprawdzić, czy „Book1.chapter22.paragraph37” istnieje przy jednym wywołaniu, ale nie zgłosić błędu odniesienia?

Robimy to za pomocą najbardziej wydajnego operatora JasvaScript, operatora in . :

"[variable||property]" in [context||root] 
>> true||false

W czasach szczytowej popularności AJAX napisałem metodę (później nazwaną) isNS (), która jest w stanie określić, czy przestrzeń nazw istnieje, w tym szczegółowe testy nazw właściwości, takie jak „Book1.chapter22.paragraph37” i wiele innych.

Ale ponieważ został wcześniej opublikowany i ze względu na jego ogromne znaczenie zasługuje na opublikowanie w osobnym wątku, nie opublikuję go tutaj, ale podam słowa kluczowe ( javascript + isNS ), które pomogą Ci zlokalizować kod źródłowy, poparty wszystkimi niezbędne wyjaśnienia.


1
inOperator sprawdza tylko istnienia właściwości, a nie wszystkie zmienne właściwości - consti letzgłoszeń nie są (i constnie są jeszcze dobrze, zmienne ).
AMN

1
consti letzostały znormalizowane za pomocą ECMAScript 2015, który został opublikowany ponad 3 lata temu i od tego czasu spotkał się z dobrym przyjęciem przez zwykłych podejrzanych i jest dziś dość rozpowszechniony, ośmielę się powiedzieć - w Github występuje ponad 2 miliony wystąpień „const” w plikach JS .
am

Tak, „zmienna” - dokładnie. Właśnie dlatego skomentowałem twoją odpowiedź, wskazując, że nie można użyć inoperatora do ogólnego sprawdzenia, czy zmienna istnieje, ponieważ „const i let are not [properties]” - chociaż constmożna powiedzieć, że wprowadza stałe odwołanie, ponieważ z drugiej strony, w przeciwieństwie do odniesienia do zmiennej , letfaktycznie wprowadza odwołanie do zmiennej - innymi słowy, jest to zmienna, a twoja odpowiedź jest nieprawidłowa, co oznacza, że ​​możesz przetestować, czy zmienna zdefiniowana za pomocą letistnieje za pomocą inoperatora - nie możesz.
am

Specyfikacja ECMAScript 6 definiuje język JavaScript, a nie ty ani przeglądarkę internetową. Dlatego nazywa się specyfikacją - jednoznacznie określa język. Twoja odpowiedź jest w najlepszym wypadku nieaktualna, w najgorszym przypadku celowo pomija się to , co uważasz za nieistotne, a jednocześnie bardzo istotne. Cytując powiązaną specyfikację, „deklaracje let i const definiują zmienne”. Te konstrukcje nie są dostępne jako właściwości windowobiektu, nie wiem, jak to dla ciebie wyjaśnić.
AMN

Odpowiedź nie obejmuje wszystkich przypadków zmiennych. W szczególności nie obejmuje zmiennych zdefiniowanych za pomocą letsłowa kluczowego. To wszystko, na co zwróciłem uwagę.
am

6

W szczególnej sytuacji opisanej w pytaniu

typeof window.console === "undefined"

jest identyczny z

window.console === undefined

Wolę ten drugi, ponieważ jest krótszy.

Pamiętaj, że szukamy consoletylko w zakresie globalnym (który jest windowobiektem we wszystkich przeglądarkach). W tej konkretnej sytuacji jest to pożądane. Nie chcemy consoledefiniować gdzie indziej.

@BrianKelley w swojej świetnej odpowiedzi wyjaśnia szczegóły techniczne. Dodałem tylko brak wniosków i przetrawiłem to w coś łatwiejszego do odczytania.


Heads-up: Twoja odpowiedź została przeniesiona tutaj z stackoverflow.com/questions/519145/...
Shog9

2
Fałszywe. ten ostatni zgłasza wyjątek w mojej konsoli.
John ktejik

6

Używam dwóch różnych sposobów w zależności od obiektu.

if( !variable ){
  // variable is either
  // 1. '';
  // 2. 0;
  // 3. undefined;
  // 4. null;
  // 5. false;
}

Czasami nie chcę oceniać pustego ciągu jako falsey, więc używam tego przypadku

function invalid( item ){
  return (item === undefined || item === null);
}

if( invalid( variable )){
  // only here if null or undefined;
}

Jeśli potrzebujesz czegoś przeciwnego, to w pierwszej kolejności zmienna staje się zmienną !!, aw nieprawidłowej funkcji === staje się! =, A nazwy funkcji zmieniają się na notInvalid.


5

Moje preferencje to typeof(elem) != 'undefined' && elem != null.

Niezależnie od tego, co wybierzesz, zastanów się nad umieszczeniem czeku w takiej funkcji

function existy (x) {
    return typeof (x) != 'undefined' && x != null;
}

Jeśli nie wiesz, że zmienna została zadeklarowana, kontynuuj od typeof (x) != 'undefined' && x != null;

Jeśli wiesz, że zmienna jest zadeklarowana, ale może nie istnieć, możesz użyć

existy(elem) && doSomething(elem);

Sprawdzana zmienna może czasami być zagnieżdżoną właściwością. Możesz użyć prop || {}, aby przejść dalej, sprawdzając istnienie danej nieruchomości:

var exists = ((((existy(myObj).prop1||{}).prop2||{}).prop3||{})[1]||{}).prop4;

Po każdej właściwości użyj (... '|| {}'). NextProp, aby brakująca właściwość nie generowała błędu.

Lub możesz użyć egy like existy(o) && existy(o.p) && existy(o.p.q) && doSomething(o.p.q)


Jeśli umieścisz go w funkcji, będzie nadmiarowy. typeof (x) != 'undefined' && x != nulljest równoważne z x != nullmomentem xzadeklarowania.
Ry-

3

To zależy od sytuacji. Jeśli szukasz czegoś, co mogło lub nie zostało zdefiniowane globalnie poza twoim kodem (na przykład jQuery), chcesz:

if (typeof(jQuery) != "undefined")

(Nie ma potrzeby ścisłej równości, typeof zawsze zwraca ciąg znaków.) Ale jeśli masz argumenty funkcji, które mogły lub nie zostały przekazane, zawsze będą zdefiniowane, ale zerowe, jeśli zostaną pominięte.

function sayHello(name) {
    if (name) return "Hello, " + name;
    else return "Hello unknown person";
}
sayHello(); // => "Hello unknown person"

3

Próbuj złapać

Jeśli zmienna w ogóle nie została zdefiniowana, możesz to sprawdzić bez wykonania kodu przerwania za pomocą bloku try-catch w następujący sposób (nie musisz use strictwłączać trybu)

BONUS: (odnosząc się do innych odpowiedzi) Dlaczego ===jest bardziej jasne niż ==( źródło )

jeśli (a == b)

Wpisz opis zdjęcia tutaj

jeśli (a === b)

Wpisz opis zdjęcia tutaj


1
Do Twojej wiadomości (a == b) umieszczenie w siatce Game of Life nie było aż tak ekscytujące.
johnsnails

0

Dziwię się, że nie wspomniano o tym jeszcze ...

oto kilka dodatkowych wariantów użycia this['var_name']

zaletą tej metody jest to, że można jej użyć przed zdefiniowaniem zmiennej.

if (this['elem']) {...}; // less safe than the res but works as long as you're note expecting a falsy value
if (this['elem'] !== undefined) {...}; // check if it's been declared
if (this['elem'] !== undefined && elem !== null) {...}; // check if it's not null, you can use just elem for the second part

// these will work even if you have an improper variable definition declared here
elem = null; // <-- no var here!! BAD!

To jest źle. window.bar=undefinedjest zdefiniowany i ustawiony na wartość. Twoja odpowiedź nie wykrywa różnicy między tym a tym, jeśli zmienna nie istnieje. Gdybyś to zrobił this.hasOwnProperty('bar'), mogłoby to zadziałać.
oligofren
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.