Jak sprawdzić niezdefiniowaną lub zerową zmienną w JavaScript?

500

Często używamy następującego wzorca kodu w naszym kodzie JavaScript

if (typeof(some_variable) != 'undefined' && some_variable != null)
{
    // Do something with some_variable
}

Czy istnieje mniej szczegółowy sposób sprawdzania, który ma taki sam efekt?

Według niektórych forów i literatury po prostu poniższe powinny mieć ten sam efekt.

if (some_variable)
{
    // Do something with some_variable
}

Niestety Firebug ocenia takie stwierdzenie, jak błąd w środowisku wykonawczym, gdy some_variablejest niezdefiniowany, podczas gdy pierwszy z nich jest w porządku. Czy to tylko (niechciane) zachowanie Firebuga, czy naprawdę jest jakaś różnica między tymi dwoma sposobami?

Tomas Vana
źródło
46
if(some_variable) { ... }nie zostanie wykonane, jeśli some_variablejest falselub 0...
kennytm
dobra uwaga;) Ale powiedzmy, że wiem, że to nie może być fałsz lub zero i chcę tylko sprawdzić, czy mogę go użyć w jakiejś logice (jako ciąg, tablicę itp.)
Tomas Vana
Powiązane: stackoverflow.com/questions/27509/…
Jørn Schou-Rode
2
... lub pusty ciąg.
David Biorąc pod uwagę
Możliwy duplikat Jak sprawdzić pusty ciąg w JavaScript?
T.Todua,

Odpowiedzi:

333

Musisz rozróżnić przypadki:

  1. Zmienne mogą być undefinedlub niezadeklarowane . Błąd pojawi się, jeśli uzyskasz dostęp do niezadeklarowanej zmiennej w innym kontekście niż typeof.
if(typeof someUndeclaredVar == whatever) // works
if(someUndeclaredVar) // throws error

Zmienna, która została zadeklarowana, ale nie została zainicjowana, to undefined.

let foo;
if (foo) //evaluates to false because foo === undefined
  1. Niezdefiniowane właściwości , takie jak someExistingObj.someUndefProperty. Niezdefiniowana właściwość nie powoduje błędu i po prostu zwraca wartość undefined, którą po przekształceniu na wartość logiczną ocenia na false. Więc jeśli nie przejmujesz się 0i falseużywanie if(obj.undefProp)jest w porządku. Istnieje wspólny idiom oparty na tym fakcie:

    value = obj.prop || defaultValue

    co oznacza „jeśli objma właściwość prop, przypisz ją value, w przeciwnym razie przypisz wartość domyślną defautValue”.

    Niektóre osoby uważają to zachowanie za mylące, argumentując, że prowadzi to do trudnych do znalezienia błędów, i inzamiast tego zalecają użycie operatora

    value = ('prop' in obj) ? obj.prop : defaultValue
użytkownik187291
źródło
1
Następnie możesz porozmawiać o hasOwnProperty i prototypach. 'indexOf' w []! == [] .hasOwnProperty ('indexOf')
Alsciende
1
Tak, myślałem o dodaniu tego, ale postanowiłem poświęcić kompletność za zwięzłość. ;)
user187291
52
nie rozwiązujesz problemu 0 i fałsz
TMS
12
Masz na myśli niezadeklarowane zmienne. Zmienna może być zadeklarowana, ale nadal ma wartość undefined.
Tgr
1
Zauważ też, że typeofzwraca ciąg. Więc nie var myVar; typeof(myVar)==undefinedwraca . falsetrue
rism
417

Myślę, że najskuteczniejszym sposobem sprawdzenia „wartości jest nulllub undefined” jest

if ( some_variable == null ){
  // some_variable is either null or undefined
}

Te dwie linie są równoważne:

if ( typeof(some_variable) !== "undefined" && some_variable !== null ) {}
if ( some_variable != null ) {}

Notatka 1

Jak wspomniano w pytaniu, krótki wariant wymaga some_variablezadeklarowania, w przeciwnym razie zostanie zgłoszony błąd ReferenceError. Jednak w wielu przypadkach użycia można założyć, że jest to bezpieczne:

sprawdź opcjonalne argumenty:

function(foo){
    if( foo == null ) {...}

sprawdź właściwości istniejącego obiektu

if(my_obj.foo == null) {...}

Z drugiej strony typeofmoże radzić sobie z niezadeklarowanymi zmiennymi globalnymi (po prostu zwraca undefined). Jednak przypadki te powinny zostać ograniczone do minimum z dobrych powodów, jak wyjaśnił Alsciende.

Uwaga 2

Ten - nawet krótszy - wariant nie jest równoważny:

if ( !some_variable ) {
  // some_variable is either null, undefined, 0, NaN, false, or an empty string
}

więc

if ( some_variable ) {
  // we don't get here if some_variable is null, undefined, 0, NaN, false, or ""
}

Uwaga 3

Ogólnie zaleca się stosowanie ===zamiast ==. Proponowane rozwiązanie stanowi wyjątek od tej reguły. Składnia sprawdzania JSHint nawet stanowi eqnullopcję dla tego powodu.

Z przewodnika po stylu jQuery :

Należy stosować ścisłe kontrole równości (===) na korzyść ==. Jedynym wyjątkiem jest sprawdzanie niezdefiniowanego i zerowego za pomocą null.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;
mar10
źródło
1
Bardzo ważna różnica (o której już wspomniano w pytaniu btw). Dlatego wszyscy używają typeof. Przepraszam, ale nie rozumiem, gdzie twoja odpowiedź jest przydatna, po prostu podajesz, co zostało powiedziane w pytaniu, a w pierwszych kilku wierszach stwierdzasz, że jest nawet niepoprawna.
TMS,
33
Przepraszam, ale muszę się nie zgodzić ;-) Używanie == nulljest najskuteczniejszym narzędziem do sprawdzania „zerowego lub niezdefiniowanego” (co jest tematem pytań). Nie jest to wcale rzadkie (używane 43 razy w jQuery 1.9.1), ponieważ bardzo często wiesz, że zmienna została zadeklarowana - lub testujesz właściwości istniejącego obiektu, takiego jak if( o.foo == null).
mar10
1
@ mar10 (aUndefinedVar == null) daje błąd „aUndefinedVar nie jest zdefiniowany” błąd nieprawdziwy.
Rannnn
7
Dzięki za tę zwięzłą opcję. W 99% mojego kodu nie ma potrzeby rozróżniania między wartością zerową a niezdefiniowaną, dlatego zwięzłość tej kontroli powoduje, że kod jest mniej zaśmiecony.
Ian Lovejoy
1
Aby zapobiec wystąpieniu błędu ReferenceEr podczas sprawdzania zmiennej globalnej, użyj window.someProperty == null. W przypadku zmiennych lokalnych możesz łatwo upewnić się, że są zadeklarowane: zamiast pisać if (...) {var local = ""}napiszvar local; if (...) { local = ""; }
Aloso
66

Sprawdzanie wartości null przy normalnej równości zwróci również wartość true dla niezdefiniowanej.

if (window.variable == null) alert('variable is null or undefined');

JS Equality

Semra
źródło
4
NaN nie równa się Nan?
Sharjeel Ahmed
2
@monotheist NaN nie jest równy NaN (patrz strona NaN MDN ). JavaScript używa IEEE-754 jako zmiennoprzecinkowego, który określa takie zachowania. Istnieją pewne przemyślenia na ten temat, patrz stackoverflow.com/a/23666623/2563765
Steven
1
@SharjeelAhmed Jest to poprawione matematycznie. NaNz równania różnicy nigdy nie można oczekiwać, że będzie równy
Thaina
28

W nowszych standardach JavaScript, takich jak ES5 i ES6, możesz po prostu powiedzieć

> Boolean(0) //false
> Boolean(null)  //false
> Boolean(undefined) //false

wszystkie zwracają wartość false, co jest podobne do sprawdzania pustych zmiennych przez Python. Więc jeśli chcesz napisać logikę warunkową wokół zmiennej, po prostu powiedz

if (Boolean(myvar)){
   // Do something
}

tutaj „null” lub „pusty ciąg” lub „niezdefiniowany” będą obsługiwane sprawnie.

Naren Yellavula
źródło
2
obsługiwany w dół do np. 5, dlaczego nie jest to bardziej znane !?
Himmators
12
OP chciał tylko, żeby test był inny, nulla undefinedinne wartości fałszowania powinny być prawdziwe!
Andre Figueiredo
1
Nie dodaje wartości warunkowej. Warunkiem ocenia dokładnie takie same i nadal zwraca false 0, NaN. Dzieje się tak, gdy chcesz uchwycić prawdziwość obiektu bez zachowania odniesienia do obiektu, abyś mógł go przechowywać, a nie jakiś potencjalnie duży obiekt. FYI jest to również równoważne z tym !!value, który pierwszy !neguje prawdziwość, a drugi ponownie to neguje.
erich2k8
> FYI jest to również równoważne wartości !!, która jest pierwsza! neguje prawdziwość. Które FYI jest równoważne z tym, if (var)które zostanie
przelane
2
Chociaż dosłownie używa się słowa kluczowego undefined , Boolean(undefined)działa, próba działania z niezdefiniowaną zmienną nie działa, i to jest cały sens sprawdzania, czy wartość jest pusta lub niezdefiniowana. To: if (Boolean(undeclareVarName)) { console.log('yes'); } else { console.log('no'); }zgłasza błąd ReferenceError z informacją: „Błąd ReferenceErr: undeclareVarName nie jest zdefiniowany”
Stephen P
22

Jeśli spróbujesz odwołać się do niezadeklarowanej zmiennej, we wszystkich implementacjach JavaScript zostanie wygenerowany błąd.

Właściwości obiektów nie podlegają tym samym warunkom. Jeśli właściwość obiektu nie została zdefiniowana, błąd nie zostanie zgłoszony, jeśli spróbujesz uzyskać do niej dostęp. W tej sytuacji możesz skrócić:

 if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null)

do

if (myObj.some_property != null)

Mając to na uwadze oraz fakt, że zmienne globalne są dostępne jako właściwości obiektu globalnego ( windoww przypadku przeglądarki), można użyć następujących zmiennych dla zmiennych globalnych:

if (window.some_variable != null) {
    // Do something with some_variable
}

W zakresach lokalnych zawsze warto upewnić się, że zmienne są zadeklarowane u góry bloku kodu, co pozwoli zaoszczędzić na powtarzających się zastosowaniach typeof.

Andy E.
źródło
11
Tęsknisz za NaN, 0 ”i fałszywym, ponieważ nie są one zerowe ani niezdefiniowane, ale również fałszywe.
Andreas Köberle,
@Andreas Köberle ma rację. Nawet niepisany operator równości mówi, że null różni się od NaN, 0, „” i false. Musisz zrobić, if (myObj.some_property != null)aby uzyskać równoważne zachowanie.
thejoshwolfe
15

Po pierwsze, musisz bardzo jasno określić, co testujesz. JavaScript ma wszelkiego rodzaju niejawne konwersje, które mogą cię zaskoczyć, oraz dwa różne rodzaje komparatorów równości: ==i ===.

Funkcja, test(val)która sprawdza nulllub undefinedpowinna mieć następujące cechy:

 test(null)         => true
 test(undefined)    => true
 test(0)            => false
 test(1)            => false
 test(true)         => false
 test(false)        => false
 test('s')          => false
 test([])           => false

Zobaczmy, które z pomysłów tutaj faktycznie przeszły nasz test.

Te prace:

val == null
val === null || val === undefined
typeof(val) == 'undefined' || val == null
typeof(val) === 'undefined' || val === null

Te nie działają:

typeof(val) === 'undefined'
!!val

Utworzyłem wpis jsperf, aby porównać poprawność i wydajność tych podejść. Na razie wyniki nie są jednoznaczne, ponieważ nie przeprowadzono wystarczającej liczby uruchomień w różnych przeglądarkach / platformach. Poświęć chwilę, aby uruchomić test na swoim komputerze!

Obecnie wydaje się, że prosty val == nulltest zapewnia najlepszą wydajność. Jest także prawie najkrótszy. Test może być zanegowany, val != nulljeśli chcesz uzupełnienia.

Drew Noakes
źródło
12

jest to jedyny przypadek, w którym ==należy zastosować:

if (val == null) console.log('val is null or undefined')
Yukulélé
źródło
3
ta odpowiedź z około 2019 r. nie ma pozytywnych opinii, ale w przypadku tego zastosowania jest to KISS. Również val != nulldla przeciwnej, tylko jeden = , a ponieważ za @Yukulele to jedyny używać ==będziesz wiedzieć, co to jest, kiedy go zobaczyć.
DKebler
7

Ponieważ nie ma jednej pełnej i poprawnej odpowiedzi, postaram się podsumować:

Ogólnie wyrażenie:

if (typeof(variable) != "undefined" && variable != null)

nie można uprościć, ponieważ variablemoże to być niezadeklarowane, więc pominięcie typeof(variable) != "undefined"spowoduje błąd ReferenceError. Ale możesz uprościć wyrażenie zgodnie z kontekstem :

Jeśli variablejest globalny , możesz uprościć:

if (window.variable != null)

Jeśli jest lokalny , prawdopodobnie można uniknąć sytuacji, w których ta zmienna nie jest zadeklarowana, a także uprościć:

if (variable != null)

Jeśli jest to właściwość object , nie musisz się martwić o ReferenceError:

if (obj.property != null)
TMS
źródło
Jest navigatorczęścią window? Kiedy otrzymamy wyjątek navigator is not defined, czy możemy skorzystać z window.navigator != nulltestu?
jww
5

Możesz po prostu sprawdzić, czy zmienna ma wartość, czy nie. Znaczenie,

if( myVariable ) {
//mayVariable is not :
//null
//undefined
//NaN
//empty string ("")
//0
//false

}

Jeśli nie wiesz, czy zmienna istnieje (to znaczy, jeśli została zadeklarowana), powinieneś sprawdzić za pomocą operatora typeof. na przykład

if( typeof myVariable !== 'undefined' ) {
    // myVariable will get resolved and it is defined
}
DDave
źródło
4

Zrobiłem to przy użyciu tej metody

zapisz identyfikator w jakiejś zmiennej

var someVariable = document.getElementById("someId");

następnie użyj warunku if

if(someVariable === ""){
 //logic
} else if(someVariable !== ""){
 //logic
}
Mab Kiani
źródło
3

Jak wspomniano w jednej z odpowiedzi, możesz mieć szczęście, jeśli mówisz o zmiennej o zasięgu globalnym. Jak zapewne wiesz, zmienne zdefiniowane globalnie mają tendencję do dodawania do obiektu Windows. Możesz skorzystać z tego faktu, więc powiedzmy, że uzyskujesz dostęp do zmiennej o nazwie bleh, po prostu użyj podwójnie odwróconego operatora (!!)

!!window['bleh'];

Zwróci to wartość false, gdy bleh nie zostanie zadeklarowane ORAZ przypisana wartość.

Farax
źródło
3

oto inny sposób użycia metody Array zawiera () :

[undefined, null].includes(value)
Jason
źródło
To nie działa! ReferenceError: wartość nie jest zdefiniowana
Sébastien Temprado
1
Powinna to być wartość, którą chcesz sprawdzić.
a2441918
2

cokolwiek yyy jest niezdefiniowane lub zerowe, zwróci wartość true

if (typeof yyy == 'undefined' || !yyy) {
    console.log('yes');
} else {
    console.log('no');
}

tak

if (!(typeof yyy == 'undefined' || !yyy)) {
    console.log('yes');
} else {
    console.log('no');
}

Nie

Terry Lin
źródło
2

Otwórz narzędzia programistyczne w przeglądarce i po prostu wypróbuj kod pokazany na poniższym obrazku.

Img1 Img2

Akash Preet
źródło
2

Aby to zrozumieć, przeanalizujmy, jaka będzie wartość zwracana przez silnik Javascript podczas konwersji niezdefiniowanych, zerowych i „” (również pusty ciąg znaków). Możesz to bezpośrednio sprawdzić na konsoli programisty.

wprowadź opis zdjęcia tutaj

Widać, że wszyscy przekształcają się w fałsz, co oznacza, że ​​wszyscy ci trzej zakładają „brak istnienia” przez javascript. Nie musisz więc jawnie sprawdzać wszystkich trzech elementów w kodzie, jak poniżej.

if (a === undefined || a === null || a==='') {
    console.log("Nothing");
} else {
    console.log("Something");
}

Chciałbym również zwrócić uwagę na jeszcze jedną rzecz.

Jaki będzie wynik Boolean (0)?

Oczywiście fałszywe. Spowoduje to utworzenie błędu w kodzie, gdy 0 jest prawidłową wartością oczekiwanego wyniku. Więc upewnij się, że to zaznaczasz podczas pisania kodu.

Code-EZ
źródło
2

Podobnie jak masz, możesz zrobić coś takiego

if (some_variable === undefined || some_variable === null) { do stuff }

gpap
źródło
2

Jest to przykład bardzo rzadkiej okazji, w której zaleca się stosowanie ==zamiast ===. Wyrażenie somevar == nullzwróci true dla undefinedi null, ale false dla wszystkiego innego (błąd, jeśli zmienna nie jest zadeklarowana).

Używając != spowoduje odwrócenie wyniku, zgodnie z oczekiwaniami.

Nowoczesne edytory nie ostrzegają przed użyciem == lub !=obsługą null, ponieważ prawie zawsze jest to pożądane zachowanie.

Najczęstsze porównania:

undeffinedVar == null     // true
obj.undefinedProp == null // true
null == null              // true
0 == null                 // false
'0' == null               // false
'' == null                // false

Spróbuj sam:

let undefinedVar;
console.table([
    { test : undefinedVar,     result: undefinedVar     == null },
    { test : {}.undefinedProp, result: {}.undefinedProp == null },
    { test : null,             result: null             == null },
    { test : false,            result: false            == null },
    { test : 0,                result: 0                == null },
    { test : '',               result: ''               == null },
    { test : '0',              result: '0'              == null },
]);
Sabo
źródło
0

Testowanie nieważności ( if (value == null)) lub nieważności (if (value != null) ) jest mniej szczegółowe niż testowanie statusu definicji zmiennej.

Ponadto testowanie if (value)(lub if( obj.property)) w celu zapewnienia istnienia zmiennej (lub właściwości obiektu) kończy się niepowodzeniem, jeśli jest zdefiniowana falsewartością logiczną . Zastrzegł emptor :)

Lucsorel
źródło
0

Obie wartości można łatwo rozróżnić za pomocą operatora ścisłego porównania:

Przykład roboczy w:

http://www.thesstech.com/tryme?filename=nullandundefined

Przykładowy kod:

function compare(){
    var a = null; //variable assigned null value
    var b;  // undefined
    if (a === b){
        document.write("a and b have same datatype.");
    }
    else{
        document.write("a and b have different datatype.");
    }   
}
Sohail Arif
źródło
0

Jeśli celem instrukcji if jest sprawdzenie wartości nulllub undefinedwartości przed przypisaniem wartości do zmiennej, możesz skorzystać z Nullish Coalescing Operator , jest on ostatecznie dostępny w JavaScript, chociaż obsługa przeglądarki jest ograniczona. Według danych z caniuse obsługiwanych jest tylko 48,34% przeglądarek (stan na kwiecień 2020 r.).

const a = some_variable ?? '';

Zapewni to, że zmienna zostanie przypisana do pustego ciągu (lub dowolnej innej wartości domyślnej), jeśli some_variablejest nulllubundefined .

Ten operator jest najbardziej odpowiedni dla twojego przypadku użycia, ponieważ nie zwraca wartości domyślnej dla innych typów wartości fałszowania, takich jak 0i ''.

Wentjun
źródło
-1

Musisz zdefiniować funkcję tego formularza:

validate = function(some_variable){
    return(typeof(some_variable) != 'undefined' && some_variable != null)
}
Ljofre
źródło
To wygeneruje ten sam błąd ReferenceError, jeśli zmienna nie zostanie zadeklarowana.
Czad
-1

W ES5 lub ES6, jeśli potrzebujesz tego sprawdzić kilka razy, możesz:

const excluded = [null, undefined, ''];

if (!exluded.includes(varToCheck) {
  // it will bee not null, not undefined and not void string
}

Vladernn
źródło
-1

Dzięki Ramda możesz po prostu zrobić R.isNil(yourValue) Lodash, a inne biblioteki pomocnicze mają tę samą funkcję.

Mark Jackson
źródło