Posso impostare le variabili su indefinito o passare indefinito come argomento?


304

Sono un po 'confuso su JavaScript undefinede nullvalori.

Cosa fa if (!testvar)effettivamente? Verifica undefinede / nullo semplicemente undefined?

Una volta definita una variabile, posso cancellarla di nuovo undefined(quindi eliminare la variabile)?

Posso passare undefinedcome parametro? Per esempio:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");

Risposte:


514

Sono un po 'confuso su Javascript indefinito e nullo.

Non essere confuso null. In genere ha senso e si comporta in modo simile ai concetti di altri linguaggi di scripting degli oggetti "null", "zero" o "Nessuno" fuori banda.

undefinedd'altra parte, è una strana stranezza JavaScript. È un oggetto singleton che rappresenta valori fuori banda, essenzialmente un secondo simile ma diverso null. Viene fuori:

  1. Quando si chiama una funzione con meno argomenti rispetto all'elenco degli argomenti negli functionelenchi di istruzioni, gli argomenti non superati vengono impostati su undefined. Puoi provarlo con es .:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    Con questo metodo non puoi distinguere tra dosomething(1)e dosomething(1, undefined); arg2sarà lo stesso valore in entrambi. Se hai bisogno di dire la differenza che puoi guardare arguments.length, ma fare argomenti opzionali del genere non è generalmente molto leggibile.

  2. Quando una funzione non ha return value;, ritorna undefined. In genere non è necessario utilizzare un tale risultato di ritorno.

  3. Quando dichiari una variabile con var aun'istruzione in un blocco, ma non hai ancora assegnato un valore, lo è undefined. Ancora una volta, non dovresti mai davvero fare affidamento su questo.

  4. L' typeofoperatore spettrale ritorna 'undefined'quando il suo operando è una variabile semplice che non esiste, invece di generare un errore come accadrebbe normalmente se si provasse a fare riferimento ad esso. (Puoi anche dargli una semplice variabile racchiusa tra parentesi, ma non un'espressione completa che coinvolge una variabile inesistente.) Neanche per questo è molto utile.

  5. Questo è controverso. Quando accedi a una proprietà di un oggetto che non esiste, non ricevi immediatamente un errore come in ogni altra lingua. Invece ottieni un undefinedoggetto. (E poi quando proverai a usare undefinedquell'oggetto più avanti nello script andrà storto in un modo strano che è molto più difficile da rintracciare che se JavaScript avesse appena lanciato un errore immediatamente.)

    Questo è spesso usato per verificare l'esistenza di proprietà:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Tuttavia, poiché è possibile assegnare undefinedcome qualsiasi altro valore:

    o.prop= undefined;

    che in realtà non rileva se la proprietà è affidabile lì. Meglio usare l' inoperatore, che non era nella versione originale di JavaScript di Netscape, ma è ora disponibile ovunque:

    if ('prop' in o)
        ...

In sintesi, undefinedè un pasticcio specifico di JavaScript, che confonde tutti. A parte gli argomenti delle funzioni opzionali, in cui JS non ha altri meccanismi più eleganti, undefineddovrebbe essere evitato. Non avrebbe mai dovuto far parte della lingua; nullavrebbe funzionato bene per (2) e (3), e (4) è un malfunzionamento che esiste solo perché all'inizio JavaScript non aveva eccezioni.

cosa fa if (!testvar)veramente? Verifica se non definito e null o solo non definito?

Tale 'truthiness' controlli di prova contro false, undefined, null, 0, NaNe le stringhe vuote. Ma in questo caso, sì, è davvero undefinedinteressato. IMO, dovrebbe essere più esplicito al riguardo e dire if (testvar!==undefined).

una volta definita una variabile posso ripulirla in indefinita (quindi eliminando la variabile).

Puoi sicuramente assegnarglielo undefined, ma questo non cancellerà la variabile. Solo l' delete object.propertyoperatore rimuove davvero le cose.

deleteè realmente pensato per le proprietà piuttosto che per le variabili in quanto tali. I browser ti permetteranno di cavartela direttamente delete variable, ma non è una buona idea e non funzionerà in modalità rigorosa ECMAScript Quinta Edizione. Se si desidera liberare un riferimento a qualcosa in modo che possa essere raccolto in modo inutile, sarebbe più normale dirlo variable= null.

posso passare indefinito come parametro?

Sì.


10
Che risposta fantastica. Ho appena fallito il test JavaScript: perfectionkills.com/javascript-quiz Più tardi rileggerò la tua risposta e riproverò il test!
Skilldrick,

1
fisso, ta. (Tendo a non preoccuparmi troppo della riassegnazione, poiché ci sono così tante cose che una sceneggiatura potrebbe ridefinire per rovinare tutto ciò che il caso generale è impossibile da risolvere.)
bobince

2
@bobince undefinedè un oggetto singleton? Cosa intendi? È un valore primitivo e non un oggetto.
Šime Vidas,

2
@Ortitudine: questo è il punto (4). Di solito non lo farei typeof foo=='undefined'; tende ad essere usato per (4a) 'foo' in windowl' undefinedannusamento globale, nel qual caso preferirei essere esplicito e dire , o (4b) testare contro il valore stesso, nel qual caso preferirei essere leggibile e dire foo===undefined. In teoria, il test typeofcontro 'undefined'potrebbe avere un caso d'uso che altri costrutti non potrebbero fornire: annusare l'esistenza di variabili locali. Tuttavia in realtà quasi sempre sai quali variabili sono dichiarate locali.
bobince

4
Un avvertimento con # 2, di solito una funzione senza returnistruzione restituisce undefined, ma se la funzione è un costruttore (invocato con l' newoperatore) restituirà il nuovo oggetto (il valore thisall'interno del costruttore) nonostante non abbia returnun'istruzione. console.log((function (){}()));ritorna undefined. console.log((new function (){}()));restituisce un oggetto.
Codice inutile

18

Non puoi (non dovresti?) Definire nulla come indefinito, poiché la variabile non sarebbe più indefinita: l'hai semplicemente definita in qualcosa.

Non puoi (non dovresti?) Passare undefineda una funzione. Se si desidera passare un valore vuoto, utilizzare nullinvece.

L'istruzione if(!testvar)verifica i valori booleani vero / falso, questo particolare verifica se testvarvaluta false. Per definizione, nulle undefinednon deve essere valutato né come trueo false, ma JavaScript valuta nullcome falsee genera un errore se si tenta di valutare una variabile non definita.

Per testare correttamente per undefinedo null, utilizzare questi:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }

1
Il triplo eguaglia anche i controlli per tipo, quindi non viene eseguita alcuna coercizione di tipo. Douglas Crockford sconsiglia di usare gli operatori del tipo-coercing ( ==e !=).
Skilldrick,

3
Puoi definire qualcosa come indefinito. var a= undefined. Puoi passare fn(undefined). Se si desidera trovare la differenza tra una proprietà non definita pdi un oggetto oe una proprietà pche è stata definita e impostata su undefined, è necessario utilizzare l' 'p' in ooperatore.
mercoledì

1
C'è un motivo per cui non si dovrebbe testare testvar === undefinedpiuttosto che il più complicato typeof(testvar) === "undefined"?
ddaa,

4
C'è un'altra buona ragione per usare un typeoftest per variabili non definite: a differenza null, undefinedè semplicemente una proprietà dell'oggetto globale e può essere essa stessa ridefinita. Richiede solo un particolare stile di codifica e un segno di uguale mancante e undefinedviene silenziosamente modificato:if (undefined = someVar) {...}
Tim Down

1
@IanGrainger: ECMAScript 5 (implementato nelle versioni correnti di tutti i browser) risolve principalmente questo problema creando undefineduna proprietà immutabile dell'oggetto globale, quindi è più sicuro di prima. Tuttavia, è ancora possibile definire una variabile mutabile chiamata undefinedall'interno di una funzione, quindi il problema non è completamente scomparso.
Tim Down

13

La differenza fondamentale è che undefinede nullrappresentano concetti diversi.

Se solo nullfosse disponibile, non saresti in grado di determinare se è nullstato impostato intenzionalmente come valore o se il valore non è stato ancora impostato a meno che tu non abbia utilizzato la rilevazione di errori ingombranti: ad es.

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Tuttavia, se si imposta intenzionalmente il valore su null, l'uguaglianza rigorosa con undefinedfallisce, consentendo in tal modo di distinguere tra nulle undefinedvalori:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Dai un'occhiata al riferimento qui invece di fare affidamento su persone sprezzanti che dicono spazzatura come "In sintesi, undefined è un pasticcio specifico di JavaScript, che confonde tutti". Solo perché sei confuso, non significa che sia un disastro.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Questo comportamento non è specifico per JavaScript e completa il concetto generalizzato che un risultato booleano può essere true, false, sconosciuta ( null), nessun valore ( undefined), o qualcosa è andato storto ( error).

http://en.wikipedia.org/wiki/Undefined_value


E nullavrebbe comunque funzionato bene. a == nullè trueperché coercizione di tipo Javascript.
sleepwalkerfx,

11

Il modo migliore per verificare la presenza di valori null è

if ( testVar !== null )
{
    // do action here
}

e per indefinito

if ( testVar !== undefined )
{
    // do action here
}

È possibile assegnare un disponibile con indefinito.

testVar = undefined;
//typeof(testVar) will be equal to undefined.

1
Il modo migliore per verificare la presenza di valori null è utilizzare !==, non!=
MBO

6

SÌ, puoi, perché indefinito è definito come indefinito.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

il tuo caso:

test("value1", undefined, "value2")

puoi anche creare la tua variabile non definita:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

5

Per rispondere alla tua prima domanda, l'operatore not ( !) forzerà tutto ciò che viene dato in un valore booleano. Così null, 0, false, NaNe ""(stringa vuota) sarà tutto appare falso.


E anche stringa vuota e NaN (non un numero)
MBO

undefinednon verrà visualizzato come false, genererà un errore "non definito".
Tatu Ulmanen,

Tatu Ulmanen: non è vero. if (undefined) {/* Do stuff*/}non genererà un errore, poiché undefinedesiste come proprietà dell'oggetto globale. Ciò che darà un errore è qualcosa del genereif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down

2

JavaScript, come impostare una variabile su indefinita dalla riga di comando:

Impostare una variabile su indefinita nel jsterminale della riga di comando javascript fornito con Java su Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Se imposti una variabile su indefinita in un javascript:

Metti questo in myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Stampa questo:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

AVVERTIMENTO! Quando si imposta la variabile su indefinita, si imposta la variabile su un'altra variabile. Se viene eseguita una persona subdola undefined = 'rm -rf /';ogni volta che imposti la variabile su indefinita, riceverai quel valore.

Forse ti starai chiedendo come posso produrre il valore indefinito alieni all'inizio e farlo funzionare ancora. È a causa del sollevamento di JavaScript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html


2

Prova questo:

// found on UglifyJS
variable = void 0;

0

Il for if (something)e if (!something)viene comunemente utilizzato per verificare se qualcosa è definito o non definito. Per esempio:

if (document.getElementById)

L'identificatore viene convertito in un valore booleano, quindi undefinedviene interpretato come false. Naturalmente ci sono anche altri valori (come 0 e '') che vengono interpretati come false, ma o l'identificatore non dovrebbe ragionevolmente avere un tale valore o sei felice di trattare un tale valore come non definito.

Javascript ha un deleteoperatore che può essere usato per cancellare un membro di un oggetto. A seconda dell'ambito di una variabile (ovvero se è globale o no) è possibile eliminarlo per renderlo indefinito.

Non esiste una undefinedparola chiave che è possibile utilizzare come valore letterale indefinito. È possibile omettere i parametri in una chiamata di funzione per renderli indefiniti, ma ciò può essere utilizzato solo inviando meno parametri alla funzione, non è possibile omettere un parametro nel mezzo.


0

Solo per divertimento, ecco un modo abbastanza sicuro per assegnare "non assegnato" a una variabile. Perché ciò abbia una collisione richiederebbe che qualcuno abbia aggiunto al prototipo di Object con esattamente lo stesso nome della stringa generata casualmente. Sono sicuro che il generatore di stringhe casuali potrebbe essere migliorato, ma ne ho appena preso uno da questa domanda: generare stringhe / caratteri casuali in JavaScript

Questo funziona creando un nuovo oggetto e provando ad accedere a una proprietà su di esso con un nome generato casualmente, che presumiamo non esisterà e avrà quindi il valore di indefinito.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.