Domanda Come verificare la presenza di "non definito" in JavaScript? [duplicare]


Questa domanda ha già una risposta qui:

Qual è il modo più appropriato per verificare se una variabile non è definita in JavaScript? Ho visto diversi modi possibili:

if (window.myVariable)

O

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

O

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

1872
2017-08-02 17:53


origine


risposte:


Se sei interessato a scoprire se una variabile è stata dichiarata indipendentemente dal suo valore, allora usa il in l'operatore è il modo più sicuro per andare. Considera questo esempio.

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

Ma questo potrebbe non essere il risultato previsto per alcuni casi, dal momento che la variabile o la proprietà è stata dichiarata, ma solo non inizializzata. Usa il in operatore per un controllo più robusto.

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

Se sei interessato a sapere se la variabile non è stata dichiarata o ha il valore undefined, quindi usa il typeof operatore.

if (typeof myVar != 'undefined')

Il typeof l'operatore è garantito per restituire una stringa. Confronti diretti contro undefined sono fastidiosi come undefined può essere sovrascritto

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

Come sottolineato da @CMS, questo è stato corretto in ECMAScript 5th ed., E undefined non è scrivibile.

if (window.myVar) includerà anche questi valori falsy, quindi non è molto robusto:

falso
0
""
NaN
nullo
non definito

Grazie a @CMS per aver segnalato che il tuo terzo caso - if (myVariable) può anche generare un errore in due casi. Il primo è quando la variabile non è stata definita che getta a ReferenceError.

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

L'altro caso è quando la variabile è stata definita, ma ha una funzione getter che genera un errore quando viene invocata. Per esempio,

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

2154
2017-08-02 17:58



Io personalmente uso

myVar === undefined

Avvertenza: si prega di notare che === è usato sopra == e quello myVar è stato in precedenza dichiarato (non definito).


non mi piace typeof myVar === "undefined". Penso che sia lungo e inutile. (Posso ottenere lo stesso risultato con meno codice.)

Ora alcune persone si lamenteranno per il dolore quando leggono questo, urlando: "Aspetta, WAAITTT !!! undefined può essere ridefinito! "

Freddo. Lo so. Inoltre, la maggior parte delle variabili in Javascript può essere ridefinita. Non dovresti mai usare un identificatore integrato che possa essere ridefinito?

Se segui questa regola, fa bene a te: non sei un ipocrita.

Il fatto è che, per fare un sacco di lavoro reale in JS, gli sviluppatori devono affidarsi a identificatori ridefinibili per essere quello che sono. Non sento le persone che mi dicono che non dovrei usare setTimeout perché qualcuno può

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

In conclusione, l'argomento "può essere ridefinito" per non usare un raw === undefined è fasullo.

(Se hai ancora paura undefined essendo ridefinito, perché stai integrando ciecamente codice libreria non testato nella tua base di codice? O ancora più semplice: uno strumento di sfilacciatura.)


Inoltre, come il typeof approccio, questa tecnica può "rilevare" le variabili non dichiarate:

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

Ma entrambe queste tecniche perdono nella loro astrazione. Vi esorto a non usare questo o addirittura

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

Prendere in considerazione:

var iAmUndefined;

Per capire se la variabile è dichiarata o meno, potresti dover ricorrere al in operatore. (In molti casi, puoi semplicemente leggere il codice O_o).

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

Ma aspetta! C'è più! Cosa succede se qualche prototipo di magia della catena sta accadendo ...? Adesso anche il superiore in l'operatore non è sufficiente. (Ok, ho finito qui per questa parte eccetto per dire che per il 99% del tempo, === undefined (e **** tosse **** typeof) funziona bene. Se ti interessa davvero, puoi leggere su questo argomento da solo.)


888
2017-08-02 18:26



utilizzando typeof è la mia preferenza Funzionerà quando la variabile non è mai stata dichiarata, diversamente da qualsiasi confronto con il == o === operatori o tipo di coercizione usando if. (undefined, a differenza di null, può anche essere ridefinito negli ambienti ECMAScript 3, rendendolo inaffidabile per confronto, anche se quasi tutti gli ambienti comuni ora sono compatibili con ECMAScript 5 o successivi).

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

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

149
2017-08-02 18:05



Devi usare typeof .

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

51
2018-06-06 20:22



Se non è definito, non sarà uguale a una stringa che contiene i caratteri "non definito", in quanto la stringa non è indefinita.

Puoi controllare il tipo di variabile:

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

A volte non devi nemmeno controllare il tipo. Se il valore della variabile non può essere valutato come falso quando è impostato (ad esempio se si tratta di una funzione), puoi semplicemente valutare la variabile. Esempio:

if (something) {
  something(param);
}

20
2018-06-06 20:23



Alcuni scenari che illustrano i risultati delle varie risposte: http://jsfiddle.net/drzaus/UVjM4/

(Si noti che l'uso di var per in i test fanno la differenza quando sono in un wrapper con scope)

Codice di riferimento:

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

E risultati:

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
2018-01-13 15:39



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

Si noti che un confronto rigoroso (!==) non è necessario in questo caso, dal momento che typeof restituirà sempre una stringa.


16
2018-06-06 20:26



In Questo articolo Ho letto questo framework come Underscore.js usa questa funzione:

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

15
2017-12-19 10:42