JavaScript: undefined! == undefined?

NOTA: come da ECMAScript5.1, sezione 15.1.1.3 , window.undefined è di sola lettura.

  • I moderni browser lo implementano correttamente. ad esempio: Safari 5.1, Firefox 7, Chrome 20, ecc.
  • Undefined è ancora modificabile in: Chrome 14, …

Quando ho recentemente integrato Facebook Connect con Tersus , inizialmente ho ricevuto i messaggi di errore Invalid Enumeration Value e il Handler already exists quando si tenta di chiamare le funzioni dell’API di Facebook.

Si è scoperto che la causa del problema era

 object.x === undefined 

restituire false quando non c’è alcuna proprietà ‘x’ in ‘object’.

Ho risolto il problema sostituendo l’uguaglianza rigorosa con l’uguaglianza regolare in due funzioni di Facebook:

 FB.Sys.isUndefined = function(o) { return o == undefined;}; FB.Sys.containsKey = function(d, key) { return d[key] != undefined;}; 

Ciò ha reso le cose funzionanti per me, ma sembra suggerire una sorta di collisione tra il codice JavaScript di Facebook e il mio.

Cosa potrebbe causare questo?

Suggerimento: è ben documentato che undefined == null mentre undefined !== null . Questo non è il problema qui. La domanda è: come mai diventiamo undefined !== undefined .

Il problema è che un valore non definito rispetto a null che usa == restituisce true. Il controllo comune per indefinito è quindi fatto in questo modo:

 typeof x == "undefined" 

questo assicura che il tipo di variabile sia davvero indefinito.

Si scopre che è ansible impostare window.undefined su qualsiasi cosa si desideri, e quindi ottenere object.x !== undefined quando object.x è il vero non definito. Nel mio caso ho inavvertitamente impostato undefined su null.

Il modo più semplice per vedere questo accada è:

 window.undefined = null; alert(window.xyzw === undefined); // shows false 

Certo, non è probabile che ciò accada. Nel mio caso l’errore era un po ‘più sottile, ed equivaleva al seguente scenario.

 var n = window.someName; // someName expected to be set but is actually undefined window[n]=null; // I thought I was clearing the old value but was actually changing window.undefined to null alert(window.xyzw === undefined); // shows false 

Vorrei pubblicare alcune informazioni importanti su undefined , che i principianti potrebbero non sapere.

Guarda il seguente codice:

  /* * Consider there is no code above. * The browser runs these lines only. */ // var a; // --- commented out to point that we've forgotten to declare `a` variable if ( a === undefined ) { alert('Not defined'); } else { alert('Defined: ' + a); } alert('Doing important job below'); 

Se si esegue questo codice, dove non è MAI STATO DICHIARATO variabile con var , si otterrà una ERROR ECCEZIONE e sorprendentemente non si vedrà alcun avviso.

Invece di “Fare un lavoro importante sotto”, lo script TERMINA INESPETTAMENTE, generando un’eccezione non gestita sulla prima riga.


Ecco l’unico modo antiproiettile per cercare undefined usando la parola chiave typeof , che è stata progettata proprio per questo scopo:

  /* * Correct and safe way of checking for `undefined`: */ if ( typeof a === 'undefined' ) { alert( 'The variable is not declared in this scope, \n' + 'or you are pointing to unexisting property, \n' + 'or no value has been set yet to the variable, \n' + 'or the value set was `undefined`. \n' + '(two last cases are equivalent, don\'t worry if it blows out your mind.' ); } /* * Use `typeof` for checking things like that */ 

Questo metodo funziona in tutti i casi possibili.

L’ultimo argomento per usarlo è che undefined può essere potenzialmente sovrascritto nelle precedenti versioni di Javascript:

  /* @ Trollface @ */ undefined = 2; /* Happy debuging! */ 

Spero di essere stato abbastanza chiaro.

È una ctriggers pratica usare l’operatore == ugality invece di === .

 undefined === undefined // true null == undefined // true null === undefined // false 

L’ object.x === undefined dovrebbe restituire true se x è una proprietà sconosciuta.

Nel capitolo Parti errate di JavaScript: The Good Parts , Crockford scrive quanto segue:

Se si tenta di estrarre un valore da un object e se l’object non ha un membro con quel nome, restituisce invece il valore non definito.

Oltre a non definito, JavaScript ha un valore simile chiamato null. Sono così simili che == pensano che siano uguali. Ciò confonde alcuni programmatori nel pensare di essere intercambiabili, portando a codice simile

 value = myObject[name]; if (value == null) { alert(name + ' not found.'); } 

Sta confrontando il valore sbagliato con l’operatore sbagliato. Questo codice funziona perché contiene due errori che si annullano a vicenda. È un modo pazzo di programmare. È meglio scrivere così:

 value = myObject[name]; if (value === undefined) { alert(name + ' not found.'); } 

Da – JQuery_Core_Style_Guidelines

  • Variabili globali:
    typeof variable === "undefined"

  • Variabili locali:
    variable === undefined

  • Proprietà:
    object.prop === undefined

 var a; typeof a === 'undefined'; // true a === undefined; // true typeof a === typeof undefined; // true typeof a === typeof sdfuwehflj; // true 

UN). Non ho mai avuto e non mi fiderò mai di alcuno strumento che pretende di produrre codice senza la codifica dell’utente, che diventa doppio in cui è uno strumento grafico.

B). Non ho mai avuto problemi con questo con Facebook Connect. È tutto ancora vecchio codice JavaScript in esecuzione in un browser e undefined===undefined ovunque tu sia.

In breve, è necessario fornire la prova che il tuo object.x era davvero indefinito e non nullo o in altro modo, perché credo che sia imansible per quello che stai descrivendo in realtà essere il caso – senza offesa 🙂 – Io metterei soldi sul problema esistente nel codice Tersus.