Hoe kan ik controleren op “undefined” in javascript?

Wat is de meest geschikte manier om te testen of een variabele niet gedefinieerd is in JavaScript?

Ik heb verschillende mogelijke manieren gezien:

if (window.myVariable)

Of

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

Of

if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?

Antwoord 1, autoriteit 100%

Als je wilt weten of een variabele is gedeclareerd, ongeacht de waarde, dan is het gebruik van de in-operator de veiligste manier om te gaan. Beschouw dit voorbeeld:

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

Maar in sommige gevallen is dit misschien niet het beoogde resultaat, omdat de variabele of eigenschap is gedeclareerd maar niet is geïnitialiseerd. Gebruik de operator in voor een meer robuuste controle.

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

Als je wilt weten of de variabele niet is gedeclareerd of de waarde undefined heeft, gebruik dan de operator typeof, die gegarandeerd een tekenreeks retourneert :

if (typeof myVar !== 'undefined')

Directe vergelijkingen met undefined zijn lastig omdat undefined kan worden overschreven.

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

Zoals @CMS al aangaf, is dit gepatcht in ECMAScript 5e ed., en undefined kan niet worden geschreven.

if (window.myVar) zal ook deze valse waarden bevatten, dus het is niet erg robuust:

vals
0
""
NaN
nul
ongedefinieerd

Dank aan @CMS voor het erop wijzen dat uw derde geval – if (myVariable) ook in twee gevallen een fout kan veroorzaken. De eerste is wanneer de variabele niet is gedefinieerd en die een ReferenceError genereert.

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

Het andere geval is wanneer de variabele is gedefinieerd, maar een getterfunctie heeft die een fout genereert wanneer deze wordt aangeroepen. Bijvoorbeeld,

// 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?
}

Antwoord 2, autoriteit 45%

Ik gebruik persoonlijk

myVar === undefined

Waarschuwing: houd er rekening mee dat === wordt gebruikt in plaats van == en dat myVar eerder is verklaard (niet gedefinieerd).


Ik hou niet van typeof myVar === "undefined". Ik vind het langdradig en onnodig. (Ik kan hetzelfde gedaan krijgen in minder code.)

Sommige mensen zullen nu omvallen van de pijn als ze dit lezen en schreeuwen: “Wacht! WAAITTT!!! undefined kan opnieuw worden gedefinieerd!”

Cool. Ik weet dit. Aan de andere kant kunnen de meeste variabelen in Javascript opnieuw worden gedefinieerd. Moet u nooit een ingebouwde identificatie gebruiken die opnieuw kan worden gedefinieerd?

Als u zich aan deze regel houdt, is dat goed voor u: u bent geen hypocriet.

Het punt is dat om veel echt werk in JS te kunnen doen, ontwikkelaars moeten vertrouwen op herdefinieerbare identifiers om te zijn wat ze zijn. Ik hoor niemand zeggen dat ik setTimeout niet moet gebruiken omdat iemand dat kan

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

Kortom, het argument “het kan opnieuw worden gedefinieerd” om geen onbewerkte === undefined te gebruiken, is nep.

(Als je nog steeds bang bent dat undefined opnieuw wordt gedefinieerd, waarom integreer je dan blindelings ongeteste bibliotheekcode in je codebasis? Of nog eenvoudiger: een linting-tool.)


Ook, net als de typeof-benadering, kan deze techniek niet-gedeclareerde variabelen “detecteren”:

if (window.someVar === undefined) {
    doSomething();
}

Maar beide technieken lekken in hun abstractie. Ik verzoek u dringend dit niet te gebruiken of zelfs

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

Overweeg:

var iAmUndefined;

Om vast te stellen of die variabele al dan niet is gedeclareerd, moet u mogelijk de operator in gebruiken. (In veel gevallen kun je gewoon de code O_o lezen).

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

Maar wacht! Er is meer! Wat als er een prototype kettingmagie plaatsvindt ? Nu is zelfs de superieure in-operator niet voldoende. (Ok, ik ben hier klaar met dit deel, behalve om te zeggen dat voor 99% van de tijd, === undefined (en ****kuch**** typeof) werkt prima. Als je er echt om geeft, kun je dit onderwerp apart lezen.)


Antwoord 3, autoriteit 9%

2020-update

Een van mijn redenen om de voorkeur te geven aan een typeof-controle (namelijk dat undefined opnieuw kan worden gedefinieerd) werd irrelevant met de massale acceptatie van ECMAScript 5. De andere, dat u kan typeof gebruiken om het type van een niet-gedeclareerde variabele te controleren, was altijd niche. Daarom raad ik nu aan om in de meeste situaties een directe vergelijking te gebruiken:

myVariable === undefined

Originele antwoord uit 2010

Het gebruik van typeof heeft mijn voorkeur. Het werkt als de variabele nooit is gedeclareerd, in tegenstelling tot elke vergelijking met de operatoren == of === of typ dwang met behulp van if. (undefined kan, in tegenstelling tot null, ook opnieuw worden gedefinieerd in ECMAScript 3-omgevingen, waardoor het onbetrouwbaar is voor vergelijking, hoewel bijna alle gangbare omgevingen nu voldoen aan ECMAScript 5 of hoger).

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

Antwoord 4, autoriteit 3%

Je kunt typeof als volgt gebruiken:

if (typeof something != "undefined") {
    // ...
}

Antwoord 5, autoriteit 2%

Update 25-07-2018

Het is bijna vijf jaar geleden dat dit bericht voor het eerst werd geplaatst en JavaScript heeft een lange weg afgelegd. Bij het herhalen van de tests in de oorspronkelijke post, vond ik geen consistent verschil tussen de volgende testmethoden:

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

Zelfs toen ik de tests aanpaste om te voorkomen dat Chrome ze zou optimaliseren, waren de verschillen onbeduidend. Als zodanig zou ik nu abc === undefined aanraden voor de duidelijkheid.

Relevante inhoud van chrome://version:

  • Google Chrome: 67.0.3396.99 (officiële versie) (64-bits) (cohort: stabiel)
  • Revisie: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@{#790}
  • OS: Windows
  • JavaScript: V8 6.7.288.46
  • Gebruikersagent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, zoals Gecko) Chrome/67.0.3396.99 Safari/537.36

Originele post 01-11-2013

In Google Chrome was het volgende iets sneller dan een typeof-test:

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

Het verschil was verwaarloosbaar. Deze code is echter beknopter en in één oogopslag duidelijker voor iemand die weet wat void 0 betekent. Merk echter op dat abc nog steeds gedeclareerd moet worden.

Zowel typeof als void waren significant sneller dan rechtstreeks vergelijken met undefined. Ik heb de volgende testindeling gebruikt in de Chrome-ontwikkelaarsconsole:

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

De resultaten waren als volgt:

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

Houd er rekening mee dat de eerste rij in milliseconden staat, terwijl de tweede rij in nanoseconden staat. Een verschil van 3,4 nanoseconden is niets. De tijden waren redelijk constant in de daaropvolgende tests.


Antwoord 6

Als het niet-gedefinieerd is, is het niet gelijk aan een tekenreeks die de tekens “undefined” bevat, aangezien de tekenreeks niet ongedefinieerd is.

U kunt het type variabele controleren:

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

Soms hoef je het type niet eens te controleren. Als de waarde van de variabele niet kan worden geëvalueerd als onwaar wanneer deze is ingesteld (bijvoorbeeld als het een functie is), kunt u de variabele gewoon evalueren. Voorbeeld:

if (something) {
  something(param);
}

Antwoord 7

if (typeof foo == 'undefined') {
 // Do something
};

Houd er rekening mee dat een strikte vergelijking (!==) in dit geval niet nodig is, aangezien typeof altijd een tekenreeks retourneert.


Antwoord 8

Enkele scenario’s die de resultaten van de verschillende antwoorden illustreren:
http://jsfiddle.net/drzaus/UVjM4/

(Merk op dat het gebruik van var voor in tests een verschil maakt in een scoped wrapper)

Code ter referentie:

(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;
    }
})();

En resultaten:

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

Antwoord 9

In dit artikel Ik heb gelezen dat frameworks zoals Underscore.js deze functie gebruiken:

function isUndefined(obj){
    return obj === void 0;
}

Antwoord 10

Persoonlijk gebruik ik altijd het volgende:

var x;
if( x === undefined) {
    //Do something here
}
else {
   //Do something else here
}

De eigenschap window.undefined kan niet worden geschreven in alle moderne browsers (JavaScript 1.8.5 of hoger). Uit de documentatie van Mozilla: https://developer.mozilla.org /en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, ik zie dit: Een reden om typeof() te gebruiken is dat het geen foutmelding geeft als de variabele niet is gedefinieerd.

Ik heb liever de benadering van het gebruik van

x === undefined 

omdat het faalt en in mijn gezicht ontploft in plaats van stil voorbij te gaan/mislukt als x niet eerder is gedeclareerd. Dit waarschuwt me dat x niet is gedeclareerd. Ik vind dat alle variabelen die in JavaScript worden gebruikt, gedeclareerd moeten worden.


Antwoord 11

De meest betrouwbare manier die ik ken om te controleren op undefined is door void 0 te gebruiken.

Dit is compatibel met zowel nieuwere als oudere browsers en kan niet worden overschreven zoals window.undefined in sommige gevallen kan.

if( myVar === void 0){
    //yup it's undefined
}

Antwoord 12

Omdat geen van de andere antwoorden me heeft geholpen, raad ik aan dit te doen. Het werkte voor mij in Internet Explorer 8:

if (typeof variable_name.value === 'undefined') {
    // variable_name is undefined
}

Antwoord 13

// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
   // These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}

Antwoord 14

    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 

Antwoord 15

In tegenstelling tot het antwoord van @Thomas Eding:

Als ik vergeet myVar in mijn code te vermelden, krijg ik myVar is not defined.

Laten we een echt voorbeeld nemen:

Ik heb een variabelenaam, maar ik weet niet zeker of deze ergens is gedeclareerd of niet.

Dan zal het antwoord van @Anurag helpen:

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.");

Antwoord 16

Ik gebruik het als een functieparameter en sluit het uit bij het uitvoeren van een functie, op die manier krijg ik de “echte” ongedefinieerde. Hoewel het wel vereist dat je je code in een functie plaatst. Ik vond dit tijdens het lezen van de jQuery-bron.

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

Je kunt natuurlijk ook gewoon typeof gebruiken. Maar al mijn code bevindt zich meestal toch in een bevattende functie, dus het gebruik van deze methode bespaart me waarschijnlijk hier en daar een paar bytes.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4 × four =

Other episodes