Perché null è un oggetto e qual è la differenza tra null e undefined?


866

Perché è nullconsiderato un objectin JavaScript?

Sta controllando

if ( object == null )
      Do something

lo stesso di

if ( !object )
      Do something

?

E anche:

Qual è la differenza tra nulle undefined?


6
Sarebbe bello se l'ultima domanda fosse aggiunta nel titolo. Le risposte qui sono fantastiche, ma il titolo potrebbe non indicare che troverai questa risposta qui
marcos.borunda,

6
Null non è un oggetto in JavaScript! typeof null === 'object'ma questo è un bug! Ecco un link Guarda tutti i video e divertiti :)
CdR

1
Mi piace usare C / C ++ come verità assiomatica per ciò che è una variabile indefinita e con valore NULL, poiché è molto semplice. Quindi guarda come si confrontano queste definizioni con le specifiche di altre lingue.
Samis,

Risposte:


1488
(name is undefined)

Tu: che cos'è name? (*)
JavaScript name :? Che cos'è un name? Non so di cosa stai parlando. Non ne hai mai parlato nameprima. Stai vedendo qualche altro linguaggio di scripting sul lato (client)?

name = null;

Tu: che cos'è name?
JavaScript: non lo so.

In breve; undefinedè dove non esiste alcuna nozione della cosa; non ha tipo e non è mai stato menzionato prima in tale ambito; nullè dove esiste la cosa, ma non si sa quale sia il valore.

Una cosa da ricordare è che null, concettualmente, non è la stessa falseo ""o tale, anche se si equivalgono dopo il casting del tipo, ovvero

name = false;

Tu: che cos'è name?
JavaScript: booleano falso.

name = '';

Tu: che cos'è name?
JavaScript: stringa vuota


*: namein questo contesto si intende una variabile che non è mai stata definita. Potrebbe essere una variabile non definita, tuttavia, name è una proprietà di quasi tutti gli elementi del modulo HTML. Va molto indietro nel tempo ed è stato istituito ben prima dell'id. È utile perché gli ID devono essere univoci ma i nomi non devono essere.


14
Ma in JavaScript, la stringa vuota '' è ancora un falso booleano.
Andreas Grech,

117
La stringa vuota non è booleana falsa, ma nel contesto di un condizionale viene interpretata come un valore falso (y) (coercizione).
Bryan Matthews,

22
Nel secondo caso, dove name = null, anziché "Non lo so", JavaScript potrebbe rispondere: l'oggetto null. A parte questo, mi piace lo stile della risposta.
Jean Vincent,

16
Piuttosto che "Non lo so", direi che la risposta nullè "niente". Null è definito precisamente come nessun valore. Vuoto, zero, nada. Niente.
mikl

50
Adoro quello stile di risposta. In generale, "Non ne hai mai parlato name prima" è vero. Tuttavia, dichiarare una variabile senza assegnare un valore ad essa ( var somevar;), sorprendentemente, comporterà comunque undefined.
MC Emperor

142

La differenza può essere sintetizzata in questo frammento:

alert(typeof(null));      // object
alert(typeof(undefined)); // undefined

alert(null !== undefined) //true
alert(null == undefined)  //true

verifica

object == nullè diverso da controllare if ( !object ).

Quest'ultimo è uguale a ! Boolean(object), perché l' !operatore unario lancia automaticamente l'operando giusto in un booleano.

Poiché è Boolean(null)uguale a falso allora !false === true.

Quindi se il tuo oggetto non è null , ma false o 0 o "" , il controllo passerà perché:

alert(Boolean(null)) //false
alert(Boolean(0))    //false
alert(Boolean(""))   //false

@kentaromiura Per noi Javascript noobs ... forse solo io ... che cos'è questa sintassi booleana (valore)? Casting a un booleano?
xr280xr,

@ xr280xr Sì, è casting. Prova String(null)a vedere un altro esempio di casting. Puoi anche fare cose stupide come Number(null + 2)... ma non dovresti :-). Ottima risposta da kentaromiura.
Squidbe,

Ricorda typeofè un operatore. Non avvolgerai l'operando tra parentesi per lo stesso motivo per cui non scriveresti var sum = 1 +(1);.
alex

124

nullnon è un oggetto , è un valore primitivo . Ad esempio, non è possibile aggiungere proprietà ad esso. A volte le persone credono erroneamente che sia un oggetto, perché typeof nullritorna "object". Ma questo è in realtà un bug (che potrebbe anche essere corretto in ECMAScript 6).

La differenza tra nulle undefinedè la seguente:

  • undefined: utilizzato da JavaScript e significa "nessun valore". Le variabili non inizializzate, i parametri mancanti e le variabili sconosciute hanno quel valore.

    > var noValueYet;
    > console.log(noValueYet);
    undefined
    
    > function foo(x) { console.log(x) }
    > foo()
    undefined
    
    > var obj = {};
    > console.log(obj.unknownProperty)
    undefined
    

    L'accesso a variabili sconosciute, tuttavia, produce un'eccezione:

    > unknownVariable
    ReferenceError: unknownVariable is not defined
    
  • null: utilizzato dai programmatori per indicare "nessun valore", ad es. come parametro di una funzione.

Esame di una variabile:

console.log(typeof unknownVariable === "undefined"); // true

var foo;
console.log(typeof foo === "undefined"); // true
console.log(foo === undefined); // true

var bar = null;
console.log(bar === null); // true

Come regola generale, dovresti sempre utilizzare === e mai == in JavaScript (== esegue tutti i tipi di conversioni che possono produrre risultati imprevisti). Il segno di spunta x == nullè un caso limite, perché funziona per entrambi nulle undefined:

> null == null
true
> undefined == null
true

Un modo comune per verificare se una variabile ha un valore è convertirlo in booleano e vedere se lo è true. Quella conversione viene eseguita ifdall'istruzione e dall'operatore booleano! ("non").

function foo(param) {
    if (param) {
        // ...
    }
}
function foo(param) {
    if (! param) param = "abc";
}
function foo(param) {
    // || returns first operand that can't be converted to false
    param = param || "abc";
}

Svantaggio di questo approccio: valgono tutti i seguenti valori false, quindi è necessario fare attenzione (ad esempio, i controlli precedenti non sono in grado di distinguere tra undefinede 0).

  • undefined, null
  • booleani: false
  • Numeri: +0, -0,NaN
  • Stringhe: ""

Puoi testare la conversione in booleano usando Booleancome una funzione (normalmente è un costruttore, da usare con new):

> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean({})
true
> Boolean([])
true

1
Perché fare riferimento +0e -0separatamente se +0 === -0?
Raynos,

6
Probabilmente perché è ancora possibile distinguere +0e -0: 1/+0 !== 1/-0.
neo

1
Questa risposta si collega a un post che rimanda a questa risposta come fonte ... probabilmente significava collegare a questo invece 2ality.com/2013/10/typeof-null.html
Ricardo Tomasi

Vero, come in C, dove le dichiarazioni di variabili non inizializzate sono considerate indefinite (le vecchie versioni potrebbero effettivamente contenere i dati di un programma precedente).
Samis,

5
"Ma questo è in realtà un bug (che potrebbe anche essere corretto in ECMAScript 6)" - fonte?
Gajus

26

Qual'è la differenza tra null e undefined ??

Una proprietà quando non ha definizione, non è definita. null è un oggetto. Il suo tipo è oggetto. null è un valore speciale che significa "nessun valore. undefined non è un oggetto, il suo tipo non è definito.

Puoi dichiarare una variabile, impostarla su null e il comportamento è identico, tranne per il fatto che vedrai "null" stampato contro "non definito". Puoi anche confrontare una variabile non definita con null o viceversa e la condizione sarà vera:

 undefined == null
 null == undefined

Fare riferimento a JavaScript Differenza tra null e non definito per maggiori dettagli.

e con la nuova modifica

if (object == null)  does mean the same  if(!object)

quando si verifica se l'oggetto è falso, entrambi soddisfano solo la condizione quando si verifica se falso , ma non quando è vero

Controlla qui: Javascript gotcha


4
Dovresti usare ===, quindi non definito! == null: D
olliej

1
presta attenzione all'ultima parte, non è corretto vedi la mia risposta;)
kentaromiura,

6
! object non è lo stesso di "object == null" ... In realtà, sono abbastanza diversi. ! object restituirà true se l'oggetto è 0, una stringa vuota, booleana false, non definita o nulla.
James,

3
Null è davvero un oggetto? Il primo collegamento fornito verifica null per tipoof, ma typeof (null) restituisce "oggetto" a causa di un errore di progettazione del linguaggio.
c4il,

2
nullnon è un oggetto. Ciò typeof null == 'object';restituisce true a causa di un bug che non può essere risolto in JavaScript (al momento, ma potrebbe cambiare in futuro).
Mohamad,

21

Prima parte della domanda:

Perché null è considerato un oggetto in JavaScript?

Si tratta di un errore di progettazione JavaScript che non possono essere corretti ora. Avrebbe dovuto essere di tipo null, non di tipo object o non averlo affatto. Richiede un controllo extra (a volte dimenticato) quando si rilevano oggetti reali ed è fonte di bug.

Seconda parte della domanda:

Controlla


if (object == null)
Do something

come

if (!object)
Do something

I due controlli sono sempre entrambi falsi ad eccezione di:

  • L'oggetto è indefinito o nullo: entrambi veri.

  • L'oggetto è primitivo e 0, ""o falso: primo controllo falso, secondo vero.

Se l'oggetto non è un primitivo, ma un vero e proprio oggetto, come new Number(0), new String("")o new Boolean(false), quindi entrambi i controlli sono false.

Quindi, se "oggetto" viene interpretato come un oggetto reale, entrambi i controlli sono sempre gli stessi. Se le primitive sono consentite, i controlli sono diversi per 0 "", e false.

In casi del genere object==null, i risultati non visibili potrebbero essere fonte di bug. L'uso di ==non è mai raccomandato, utilizzare ===invece.

Terza parte della domanda:

E anche:

qual è la differenza tra null e indefinito?

In JavaScript, una differenza è che null è di tipo object e non definito è di tipo non definito.

In JavaScript, null==undefinedè vero e considerato uguale se il tipo viene ignorato. Perché l'hanno deciso, ma 0 ""e false non sono uguali, non lo so. Sembra essere un'opinione arbitraria.

In JavaScript, null===undefinednon è vero poiché il tipo deve essere lo stesso in ===.

In realtà, null e indefinito sono identici, poiché entrambi rappresentano la non esistenza. Quindi fai 0, e anche ""per quello, e forse i contenitori vuoti []e {}. Così tanti tipi dello stesso niente sono una ricetta per i bug. Un tipo o nessuno è migliore. Vorrei provare a usare il minor numero possibile.

'false', 'true' e '!' sono un'altra borsa di worm che potrebbe essere semplificata, per esempio, if(!x)e if(x)da soli sono sufficienti, non hai bisogno di vero e falso.

Un var xtipo dichiarato è indefinito se non viene fornito alcun valore, ma dovrebbe essere uguale a se x non fosse mai stato dichiarato affatto. Un'altra fonte di bug è un contenitore vuoto nulla. Quindi è meglio dichiararlo e definirlo insieme, come var x=1.

Le persone girano in tondo cercando di capire tutti questi vari tipi di niente, ma è la stessa cosa in complicati vestiti diversi. La realtà è

undefined===undeclared===null===0===""===[]==={}===nothing

E forse tutti dovrebbero generare eccezioni.


8
Ottima risposta, ma va un po 'troppo lontano con []: " In realtà, null e indefinito sono identici ... e forse i contenitori vuoti [] e {}. " Probabilmente potresti convincermi a pensare che {} dovrebbe essere un po' sapore di null, ma la mia impressione è che non dovrebbe. Ma meno controverso, un array vuoto []ha comprensibilmente una .push()funzione , quindi non c'è alcun buon argomento per [] essere nullo. $ 0,02.
ruffin,

11
var x = null;

x è definito come nullo

y non è definito; // perché non l'ho definito

if (!x)

null viene valutato come falso


8

Un modo per dare un senso a null e indefinito è capire dove si verifica ciascuno di essi.

Aspettati un valore di ritorno nullo nelle seguenti situazioni:

  • Metodi che interrogano il DOM

    console.log(window.document.getElementById("nonExistentElement"));
    //Prints: null
  • Risposte JSON ricevute da una richiesta Ajax


    {
      name: "Bob",
      address: null
    }
  • RegEx.exec .

  • Nuova funzionalità che è in uno stato di flusso. Quanto segue restituisce null:


        var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));

       // But this returns undefined:

        Object.getOwnPropertyDescriptor({}, "a");

Tutti gli altri casi di inesistenza sono indicati da undefined (come notato da @Axel). Ognuna delle seguenti stampe "non definita":

    var uninitalised;
    console.log(uninitalised);

    var obj = {};
    console.log(obj.nonExistent);

    function missingParam(missing){
        console.log(missing);
    }

    missingParam();

    var arr = [];
    console.log(arr.pop());        

Naturalmente se decidi di scrivere var unitialised = null; o restituisci null da un metodo tu stesso allora hai null che si verifica in altre situazioni. Ma dovrebbe essere abbastanza ovvio.

Un terzo caso è quando si desidera accedere a una variabile ma non si sa nemmeno se è stata dichiarata. In tal caso, utilizzare typeof per evitare un errore di riferimento:

if(typeof unknown !== "undefined"){
    //use unknown
}

In sintesi, verifica la presenza di null durante la manipolazione del DOM, la gestione di Ajax o l'utilizzo di determinate funzioni di ECMAScript 5. Per tutti gli altri casi è sicuro verificare che non siano definiti con una rigorosa uguaglianza:

if(value === undefined){
  // stuff
}

8

Confronto di molti diversi controlli null in JavaScript:

http://jsfiddle.net/aaronhoffman/DdRHB/5/

// Variables to test
var myNull = null;
var myObject = {};
var myStringEmpty = "";
var myStringWhiteSpace = " ";
var myStringHello = "hello";
var myIntZero = 0;
var myIntOne = 1;
var myBoolTrue = true;
var myBoolFalse = false;
var myUndefined;

...trim...

http://aaron-hoffman.blogspot.com/2013/04/javascript-null-checking-undefined-and.html

Grafico di confronto controllo null JavaScript


1
fa "var myUndefined;" definire la variabile (come variabile nota con tipo sconosciuto)?
Qi Fan,

6

null e undefined sono entrambi false per l'uguaglianza di valore (null == undefined): entrambi collassano in booleano false. Non sono lo stesso oggetto (null! == undefined).

undefined è una proprietà dell'oggetto globale ("finestra" nei browser), ma è un tipo primitivo e non un oggetto stesso. È il valore predefinito per le variabili e le funzioni non inizializzate che terminano senza un'istruzione return.

null è un'istanza di Object. null viene utilizzato per i metodi DOM che restituiscono oggetti di raccolta per indicare un risultato vuoto, che fornisce un valore falso senza indicare un errore.


5

Alcune precisazioni:

null e undefined sono due valori diversi. Uno rappresenta l'assenza di un valore per un nome e l'altro rappresenta l'assenza di un nome.


Cosa succede in un modo ifcome segue per if( o ):

Viene valutata l'espressione tra parentesi o, quindi i ifcalci nel tipo-costringendo il valore dell'espressione tra parentesi - nel nostro caso o.

I valori falsi (che verranno costretti a falsi) in JavaScript sono: '', null, undefined, 0 e false .


5

Per aggiungere alla risposta di Qual è la differenza tra undefinedenull , da JavaScript Definitive Guide 6th Edition, p.41 in questa pagina :

Si potrebbe considerare undefineddi rappresentare l'assenza di valore nulla livello di sistema, imprevista o simile a un errore e rappresentare un'assenza di valore a livello di programma, normale o prevista. Se è necessario assegnare uno di questi valori a una variabile o proprietà o passare uno di questi valori a una funzione, nullè quasi sempre la scelta giusta.


3

nullè un oggetto. Il suo tipo è nullo. undefinednon è un oggetto; il suo tipo è indefinito.


11
sbagliato - entrambi nulle undefinedsono valori primitivi - typeof null === 'object'è un errore di linguaggio, perchéObject(null) !== null
Christoph

No non è. Object () opera getto in quel modo, vedere ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - 15.2.2.1 new Object ([valore]) ... 8. (Il valore dell'argomento non è stato fornito o il suo tipo era Null o Non definito.) Creare un nuovo oggetto ECMAScript nativo. La proprietà [[Prototype]] dell'oggetto appena costruito è impostata sull'oggetto prototipo Object. La proprietà [[Class]] dell'oggetto appena costruito è impostata su "Oggetto". L'oggetto appena costruito non ha proprietà [[Valore]]. Restituisce l'oggetto nativo appena creato.
kentaromiura,

3
@Christoph: Voglio dire, hai ragione. null dovrebbe essere un tipo, ciò che intendo è che non puoi controllarlo in questo modo perché: alert (new Object ()! == new Object ()); / * vero, la nuova istanza non è la stessa istanza / avviso (Object (null) .constructor == {} .constructor); / true come in spec / alert (Object (null) .prototype == {} .prototype); / true come in spec / alert (null instanceof Object); / ovviamente falso, null significa che non è istanziato * / Ma fondamentalmente è un bug di specifica XD vedi: uselesspickles.com/blog/2006/06/12/… e javascript.crockford.com/remedial.html
kentaromiura

2

La seguente funzione mostra perché ed è in grado di capire la differenza:

function test() {
        var myObj = {};
        console.log(myObj.myProperty);
        myObj.myProperty = null;
        console.log(myObj.myProperty);
}

Se chiami

test();

Stai arrivando

non definito

nullo

I primi console.log(...)cerca di ottenere myPropertydal myObjmentre non è ancora definito - in modo che viene di nuovo "indefinito". Dopo avergli assegnato null, il secondo console.log(...)restituisce ovviamente "null" perché myPropertyesiste, ma gli viene nullassegnato il valore .

Per poter interrogare questa differenza, JavaScript ha nulle undefined: While nullis - proprio come in altre lingue un oggetto, undefinednon può essere un oggetto perché non è disponibile alcuna istanza (nemmeno nullun'istanza).


2

Ad esempio window.someWeirdPropertynon è definito, quindi

"window.someWeirdProperty === null" valuta falso while

"window.someWeirdProperty === undefined" valuta vero.

Inoltre checkif if (!o)non è lo stesso come il controllo if (o == null)per oessere false.


Puoi elaborare la differenza tra le due condizioni
rahul,

leggi la mia risposta, significa che se o è uguale a 0, falso o "" il valore booleano è falso: var undef, vario = [0, "", null, false, undef]; per (var obj in vari) {alert (! obj); // 4 volte falso in IE, 5 in FF;)}
kentaromiura,

2

L'altra cosa divertente di null, rispetto a undefined, è che può essere incrementato.

x = undefined
x++
y = null
y++
console.log(x) // NaN
console.log(y) // 0

Ciò è utile per impostare valori numerici predefiniti per i contatori. Quante volte hai impostato una variabile su -1 nella sua dichiarazione?


2

In Javascript null non è un objecttipo, è un primitavetipo.

Qual è la differenza? Undefined si riferisce a un puntatore che non è stato impostato. Null si riferisce al puntatore null, ad esempio qualcosa ha impostato manualmente una variabile per essere di tiponull


2

Guarda questo:

   <script>
function f(a){
  alert(typeof(a));
  if (a==null) alert('null');
  a?alert(true):alert(false);
}
</script>
                                          //return:
<button onclick="f()">nothing</button>    //undefined    null    false
<button onclick="f(null)">null</button>   //object       null    false
<button onclick="f('')">empty</button>    //string               false
<button onclick="f(0)">zero</button>      //number               false
<button onclick="f(1)">int</button>       //number               true
<button onclick="f('x')">str</button>     //string               true

1

Da "I principi del Javascript orientato agli oggetti" di Nicholas C. Zakas

Ma perché un oggetto quando il tipo è null? (In effetti, questo è stato riconosciuto come errore da TC39, il comitato che progetta e mantiene JavaScript. Si potrebbe pensare che null sia un puntatore oggetto vuoto, rendendo "oggetto" un valore di ritorno logico, ma è comunque confuso.)

Zakas, Nicholas C. (2014-02-07). I principi di JavaScript orientato agli oggetti (posizioni Kindle 226-227). Pressa senza amido. Edizione Kindle.

Detto ciò:

var game = null; //typeof(game) is "object"

game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = {}; 
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;

Caso indefinito:

var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.

1

Il modo migliore per pensare a 'null' è ricordare come viene usato il concetto simile nei database, dove indica che un campo non contiene "nessun valore".

  • Sì, il valore dell'articolo è noto; esso è 'definito.' Esso è stato inizializzato.
  • Il valore dell'articolo è: "non esiste alcun valore".

Questa è una tecnica molto utile per scrivere programmi che sono più facilmente sottoposti a debug. Una variabile "non definita" potrebbe essere il risultato di un bug ... (come lo sapresti?) ... ma se la variabile contiene il valore "null", sai che "qualcuno, da qualche parte in questo programma, lo imposta su 'null.' "Pertanto, suggerisco che, quando è necessario eliminare il valore di una variabile, non" eliminare "... impostarlo su" null ". Il vecchio valore verrà lasciato orfano e presto verrà raccolto. il nuovo valore è "non esiste alcun valore (ora)". In entrambi i casi, lo stato della variabile è certo: "ovviamente, deliberatamente, è arrivato in quel modo".


1
  1. Non definito significa che è stata dichiarata una variabile ma non è stato assegnato alcun valore mentre Null può essere assegnato a una variabile che rappresenta "nessun valore". (Null è un operatore di assegnazione)

2.Undefined è un tipo stesso mentre Null è un oggetto.

3.Javascript stesso può inizializzare qualsiasi variabile non assegnata a indefinita, ma non può mai impostare il valore di una variabile su null. Questo deve essere fatto programmaticamente.

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.