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.