Jak sprawdzić "undefined" w JavaScript? [duplikat]

To pytanie ma już odpowiedź tutaj:

Jaki jest najbardziej odpowiedni sposób na sprawdzenie, czy zmienna jest niezdefiniowana w JavaScript? Widziałem kilka możliwych sposobów:

if (window.myVariable)

Lub

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

Lub

if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?
Author: Peter Mortensen, 2010-08-02

16 answers

Jeśli chcesz dowiedzieć się, czy zmienna została zadeklarowana niezależnie od jej wartości, to użycie operatora in jest najbezpieczniejszym sposobem. Rozważ ten przykład.

// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"

Ale może to nie być zamierzony wynik w niektórych przypadkach, ponieważ zmienna lub właściwość została zadeklarowana, ale po prostu nie została zainicjowana. Użyj operatora in, aby uzyskać dokładniejszą kontrolę.

"theFu" in window; // true
"theFoo" in window; // false

Jeśli chcesz wiedzieć, czy zmienna nie została zadeklarowana lub ma wartość undefined, następnie użyj operatora typeof.

if (typeof myVar != 'undefined')

Operator typeof ma zagwarantowane zwrócenie ciągu znaków. Bezpośrednie porównania z undefined są kłopotliwe, ponieważ undefined można nadpisać.

window.undefined = "omg";
"omg" == undefined // true

Jak zauważył @CMS, zostało to poprawione w ECMAScript 5th ed. i undefined jest nie do zapisania.

if (window.myVar) będzie również zawierać te fałszywe wartości, więc nie jest to bardzo solidne:

false
0
""
NaN
null
undefined

Podziękowania dla @CMS za zwrócenie uwagi, że twój trzeci przypadek - if (myVariable) może również rzucić błąd w dwóch przypadkach. Pierwsza dotyczy sytuacji, gdy zmienna nie została zdefiniowana, która rzuca ReferenceError.

// abc was never declared.
if (abc) {
    // ReferenceError: abc is not defined
} 

Drugi przypadek dotyczy sytuacji, gdy zmienna została zdefiniowana, ale ma funkcję getter, która powoduje błąd podczas wywoływania. Na przykład,

// or it's a property that can throw an error
Object.defineProperty(window, "myVariable", { 
    get: function() { throw new Error("W00t?"); }, 
    set: undefined 
});
if (myVariable) {
    // Error: W00t?
}
 2200
Author: Anurag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-01 11:28:30

Ja osobiście używam

myVar === undefined

Uwaga: Należy pamiętać, że === jest używane nad == i że myVar zostało wcześniej zadeklarowane (Nie zdefiniowane ).


Nie lubię typeof myVar === "undefined". Myślę, że jest długi i niepotrzebny. (Mogę zrobić to samo w mniejszym kodzie.)

Teraz niektórzy ludzie będą się klepać z bólu, kiedy to przeczytają, krzycząc: "czekaj! WAAITTT!!! undefined można przedefiniować!"

Super. Wiem o tym. Z drugiej strony, większość zmiennych w Javascript można przedefiniować. Czy nigdy nie należy używać wbudowanego identyfikatora, który można przedefiniować?

Jeśli zastosujesz się do tej zasady, dobrze dla Ciebie: nie jesteś hipokrytą.

Rzecz w tym, że aby wykonać wiele prawdziwej pracy w JS, programiści muszą polegać na identyfikowalnych identyfikatorach, aby były tym, czym są. Nie słyszę ludzi mówiących mi, że nie powinienem używać setTimeout ponieważ ktoś może

window.setTimeout = function () {
    alert("Got you now!");
};

Podsumowując, argument" można przedefiniować", aby nie używać raw === undefined jest fałszywy.

(jeśli nadal boisz się przedefiniowania undefined, dlaczego ślepo integrujesz niesprawdzony kod biblioteki z bazą kodu? Lub jeszcze prościej: narzędzie linting.)


Ponadto, podobnie jak podejście typeof, technika ta może "wykrywać" zmienne nierejestrowane:
if (window.someVar === undefined) {
    doSomething();
}

Ale obie te techniki przeciekają w swojej abstrakcji. Namawiam, aby nie używać tego lub nawet

if (typeof myVar !== "undefined") {
    doSomething();
}

Rozważmy:

var iAmUndefined;

Aby dowiedzieć się, czy ta zmienna jest zadeklarowana, czy nie, należy może zaistnieć potrzeba skorzystania z operatora in. (W wielu przypadkach można po prostu odczytać kod O_o).

if ("myVar" in window) {
    doSomething();
}

Ale czekaj! To nie wszystko! A co jeśli dzieje się jakaś magia łańcuchów prototypów? Teraz nawet Operator superior in nie wystarczy. (Ok, skończyłem z tą częścią, z wyjątkiem tego, że przez 99% czasu, === undefined (i * * * * kaszel**** typeof) działa dobrze. Jeśli naprawdę Ci zależy, możesz przeczytać na ten temat samodzielnie.)

 918
Author: Thomas Eding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-28 08:02:01

Używanie typeof jest moją preferencją. Będzie działać, gdy zmienna nigdy nie została zadeklarowana, w przeciwieństwie do jakiegokolwiek porównania z operatorami == lub === lub typu przymus przy użyciu if. (undefined, W przeciwieństwie do null, może być również ponownie zdefiniowany w środowiskach ECMAScript 3, co czyni go niewiarygodnym dla porównania, chociaż prawie wszystkie popularne środowiska są teraz zgodne z ECMAScript 5 lub nowszymi).

if (typeof someUndeclaredVariable == "undefined") {
    // Works
}

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}
 155
Author: Tim Down,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-05 08:37:38

Musisz użyć typeof .

if (typeof something != "undefined") {
    // ...
}
 53
Author: Jacob Relkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-04 23:09:04

Jeśli jest niezdefiniowany, nie będzie równy łańcuchowi zawierającemu znaki "undefined", ponieważ łańcuch nie jest niezdefiniowany.

Możesz sprawdzić typ zmiennej:

if (typeof(something) != "undefined") ...

Czasami nawet nie trzeba sprawdzać typu. Jeśli wartość zmiennej nie może być obliczona na false, gdy jest ustawiona (na przykład jeśli jest funkcją), wtedy można po prostu ocenić zmienną. Przykład:

if (something) {
  something(param);
}
 20
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-06 20:33:01

Niektóre scenariusze ilustrujące wyniki różnych odpowiedzi: http://jsfiddle.net/drzaus/UVjM4/

(zauważ, że użycie var do testów in robi różnicę, gdy w opakowaniu z lunetą)

Kod odniesienia:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

I wyniki:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
 17
Author: drzaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-13 17:18:23
if (typeof foo == 'undefined') {
 // Do something
};

Zauważ, że ścisłe porównanie (!==) nie jest w tym przypadku konieczne, ponieważ typeof zawsze zwróci ciąg znaków.

 16
Author: Mathias Bynens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-06 20:26:37

W Ten artykuł przeczytałem, że frameworki jak podkreślają.JS Użyj tej funkcji:

function isUndefined(obj){
    return obj === void 0;
}
 15
Author: Marthijn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-23 13:39:38

Najbardziej wiarygodnym sposobem sprawdzania undefined jest użycie void 0.

Jest to zgodne z nowszymi i starszymi przeglądarkami i nie można go nadpisać, jak window.undefined może w niektórych przypadkach.

if( myVar === void 0){
    //yup it's undefined
}
 10
Author: Joseph Gabriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 13:20:54

Osobiście zawsze używam:

var x;
if( x === undefined) {
    //Do something here
}
else {
   //Do something else here
}
Okno.niezdefiniowana właściwość nie jest zapisywalna we wszystkich nowoczesnych przeglądarkach (JavaScript 1.8.5 lub nowszy). Z Dokumentacji Mozilli: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined , widzę to: jednym z powodów użycia metody typeof jest to, że nie powoduje błędu, jeśli zmienna nie została zdefiniowana.

Wolę mieć podejście do używania

x === undefined 

Ponieważ zawodzi i wybucha mi w twarz, a nie po cichu przechodząc / upadając, jeśli x nie został wcześniej zadeklarowany. To ostrzega mnie, że x nie jest deklarowany. Uważam, że wszystkie zmienne używane w JavaScript powinny być zadeklarowane.

 9
Author: Hrishi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 13:58:10

Aktualizacja 2018-07-25

Minęło prawie pięć lat od pierwszego napisania tego postu, a JavaScript przeszedł długą drogę. Powtarzając testy w oryginalnym poście, nie znalazłem spójnej różnicy między następującymi metodami testowymi:

  • abc === undefined
  • abc === void 0
  • typeof abc == 'undefined'
  • typeof abc === 'undefined'

Nawet kiedy zmodyfikowałem testy, aby zapobiec ich optymalizacji przez Chrome, różnice były znikome. W związku z tym polecam teraz abc === undefined dla jasność.

Odpowiednia treść z chrome://version:

    Google Chrome: 67.0.3396.99 (Official Build) (64-bit) (kohorta: Stable)
  • Revision: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@{#790}
  • OS: Windows
  • JavaScript: V8 6.7.288.46
  • W 2009 roku firma Microsoft wprowadziła do swojej oferty System operacyjny Windows 10.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

Original post 2013-11-01

W Google Chrome, poniższy był nieco szybszy niż typeof test:

if (abc === void 0) {
    // Undefined
}

Różnica była znikoma. Jednak ten kod jest bardziej zwięzły i jaśniejszy na pierwszy rzut oka dla kogoś, kto wie, co oznacza {10]}. Należy jednak pamiętać, że abc nadal musi być zadeklarowana.

Zarówno typeof, jak i void były znacznie szybsze niż porównywanie bezpośrednio z undefined. Używałem następującego formatu testowego w konsoli deweloperskiej Chrome:

var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
    if (TEST) {
        void 1;
    }
}
end = +new Date();
end - start;

Wyniki były jak następuje:

Test: | abc === undefined      abc === void 0      typeof abc == 'undefined'
------+---------------------------------------------------------------------
x10M  |     13678 ms               9854 ms                 9888 ms
  x1  |    1367.8 ns              985.4 ns                988.8 ns

Zauważ, że pierwszy wiersz jest w milli sekund, podczas gdy drugi wiersz jest w nano sekund. Różnica 3,4 nanosekundy to nic. Czasy były dość spójne w kolejnych testach.

 9
Author: Zenexer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-26 03:36:54

Ponieważ żadna z innych odpowiedzi mi nie pomogła, proponuję zrobić to. U mnie działało w Internet Explorerze 8:

if (typeof variable_name.value === 'undefined') {
    // variable_name is undefined
}
 4
Author: anmarti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-23 13:31:46
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
   // These statements execute.
}

if (x === undefined) { // Throws a ReferenceError

}
 3
Author: sourcecode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-23 13:38:10

W przeciwieństwie do @ Thomas Eding odpowiedź:

Jeśli zapomnę zadeklarować myVar w moim kodzie, to dostanę myVar is not defined.

Weźmy prawdziwy przykład:

Mam nazwę zmiennej, ale nie jestem pewien, czy jest ona gdzieś zadeklarowana, czy nie.

Wtedy odpowiedź @Anurag pomoże:

var myVariableToCheck = 'myVar';
if (window[myVariableToCheck] === undefined)
    console.log("Not declared or declared, but undefined.");

// Or you can check it directly 
if (window['myVar'] === undefined) 
    console.log("Not declared or declared, but undefined.");
 3
Author: Vikas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-23 13:41:10
    var x;
    if (x === undefined) {
        alert ("I am declared, but not defined.")
    };
    if (typeof y === "undefined") {
        alert ("I am not even declared.")
    };

    /* One more thing to understand: typeof ==='undefined' also checks 
       for if a variable is declared, but no value is assigned. In other 
       words, the variable is declared, but not defined. */

    // Will repeat above logic of x for typeof === 'undefined'
    if (x === undefined) {
        alert ("I am declared, but not defined.")
    };
    /* So typeof === 'undefined' works for both, but x === undefined 
       only works for a variable which is at least declared. */

    /* Say if I try using typeof === undefined (not in quotes) for 
       a variable which is not even declared, we will get run a 
       time error. */

    if (z === undefined) {
        alert ("I am neither declared nor defined.")
    };
    // I got this error for z ReferenceError: z is not defined 
 1
Author: Gaurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-23 13:37:02

Używam go jako parametru funkcji i wykluczam go podczas wykonywania funkcji, w ten sposób otrzymuję "rzeczywisty" niezdefiniowany. Chociaż wymaga to umieszczenia kodu wewnątrz funkcji. Znalazłem to podczas czytania źródła jQuery.

undefined = 2;

(function (undefined) {
   console.log(undefined); // prints out undefined
   // and for comparison:
   if (undeclaredvar === undefined) console.log("it works!")
})()

Oczywiście możesz po prostu użyć typeof chociaż. Ale cały mój kod jest zwykle wewnątrz funkcji zawierającej, więc korzystanie z tej metody prawdopodobnie oszczędza mi kilka bajtów tu i ówdzie.

 0
Author: Cristian Sanchez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-02 18:02:21