Por que nulo é um objeto e qual a diferença entre nulo e indefinido?

866

Por que é nullconsiderado umobject em JavaScript?

Está verificando

if ( object == null )
      Do something

o mesmo que

if ( !object )
      Do something

?

E também:

Qual é a diferença entre nulle undefined?

rahul
fonte
6
Seria ótimo se a última pergunta fosse adicionada no título. As respostas aqui são impressionantes, mas o título não pode apontar que você vai encontrar esta resposta aqui
marcos.borunda
6
Nulo não é um objeto em JavaScript! typeof null === 'object'mas isso é um bug! Aqui está um link Assista a todos os vídeos e divirta-se :)
CoR
1
Eu gosto de usar C / C ++ como a verdade axiomática do que é uma variável indefinida e com valor NULL, pois é muito direta. Então veja como essas definições se comparam às especificações de outros idiomas.
samis 03/02

Respostas:

1488
(name is undefined)

Você: O que é name? (*)
JavaScript name :? O que é um name? Não sei do que você está falando. Você nunca mencionou isso nameantes. Você está vendo alguma outra linguagem de script no lado (cliente)?

name = null;

Você: O que é name?
JavaScript: não sei.

Em resumo; undefinedé onde não existe noção da coisa; não tem tipo e nunca foi mencionado anteriormente nesse escopo; nullé onde a coisa é conhecida por existir, mas não se sabe qual é o valor.

Uma coisa a lembrar é que nullnão é, conceitualmente, o mesmo que falseou aquilo , mesmo que sejam iguais ""após a conversão do tipo, ou seja,

name = false;

Você: O que é name?
JavaScript: booleano falso.

name = '';

Você: O que é name?
JavaScript: String vazia


*: nameneste contexto, entende-se como uma variável que nunca foi definida. Pode ser qualquer variável indefinida, no entanto, name é uma propriedade de praticamente qualquer elemento de formulário HTML. Vai muito, muito tempo atrás e foi instituído bem antes do id. É útil porque os IDs devem ser exclusivos, mas os nomes não precisam ser.

Roubar
fonte
14
Mas no JavaScript, a string vazia '' ainda é um falso booleano.
Andreas Grech
117
A cadeia vazia não é booleana false, mas no contexto de uma condicional é interpretada como um valor false (y) (coerção).
Bryan Matthews
22
Para o segundo caso, em que name = null, em vez de 'não sei', o JavaScript pode responder: O objeto nulo. Fora isso, eu gosto do estilo da resposta.
Jean Vincent
16
Em vez de "não sei", diria que a resposta nullé "nada". Nulo é definido com precisão como sem valor. Vazio, nada, nada. Nada.
Mikl
50
Ame esse estilo de resposta. Em geral, "Você nunca mencionou nada name antes" é verdade. No entanto, declarar uma variável sem atribuir um valor a ela ( var somevar;), surpreendentemente, ainda resultará em undefined.
MC Emperor
142

A diferença pode ser resumida neste snippet:

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

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

Verificando

object == nullé diferente de verificar if ( !object ).

Este último é igual a ! Boolean(object), porque o unário! operador converte automaticamente o operando certo em um Booleano.

Desde Boolean(null)igual a falso então !false === true.

Portanto, se seu objeto não for nulo , mas falso ou 0 ou "" , a verificação será aprovada porque:

alert(Boolean(null)) //false
alert(Boolean(0))    //false
alert(Boolean(""))   //false
kentaromiura
fonte
@kentaromiura Para nós Javascript noobs ... talvez apenas eu ... o que é essa sintaxe booleana (valor)? Transmitindo para um booleano?
Xr280xr
@ xr280xr Sim, está lançando. Tente String(null)ver outro exemplo de transmissão. Você pode até fazer coisas tolas como Number(null + 2)... mas você não deve :-). Excelente resposta de kentaromiura.
squidbe
Lembre typeof- se é um operador. Você não colocaria o operando entre parênteses pelo mesmo motivo que não escreveria var sum = 1 +(1);.
alex
124

nullnão é um objeto , é um valor primitivo . Por exemplo, você não pode adicionar propriedades a ele. Às vezes, as pessoas assumem erroneamente que é um objeto, porque typeof nullretorna "object". Mas isso é realmente um bug (que pode até ser corrigido no ECMAScript 6).

A diferença entre nulle undefinedé a seguinte:

  • undefined: usado por JavaScript e significa "sem valor". Variáveis ​​não inicializadas, parâmetros ausentes e variáveis ​​desconhecidas têm esse valor.

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

    Acessar variáveis ​​desconhecidas, no entanto, produz uma exceção:

    > unknownVariable
    ReferenceError: unknownVariable is not defined
  • null: usado pelos programadores para indicar “sem valor”, por exemplo, como parâmetro para uma função.

Examinando uma variável:

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

Como regra geral, você sempre deve usar === e nunca == no JavaScript (== executa todos os tipos de conversões que podem produzir resultados inesperados). A verificação x == nullé um caso delicado, porque funciona para ambos nulle undefined:

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

Uma maneira comum de verificar se uma variável tem um valor é convertê-la em booleano e verificar se é true. Essa conversão é realizada pela ifinstrução e pelo operador booleano! ("não").

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";
}

Desvantagem dessa abordagem: Todos os valores a seguir são avaliados false, então você deve ter cuidado (por exemplo, as verificações acima não podem distinguir entre undefinede 0).

  • undefined, null
  • Booleanos: false
  • Números: +0, -0,NaN
  • Cordas: ""

Você pode testar a conversão em booleano usando Booleancomo uma função (normalmente é um construtor, para ser usado com new):

> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean({})
true
> Boolean([])
true
Axel Rauschmayer
fonte
1
Por que referenciar +0e -0separadamente se +0 === -0?
Raynos
6
Provavelmente porque você ainda pode distinguir +0e -0: 1/+0 !== 1/-0.
neo
1
Esta resposta links para um post que links para esta resposta como fonte ... provavelmente destinados a ligação a esta vez 2ality.com/2013/10/typeof-null.html
Ricardo Tomasi
Ah, certo, como em C, onde declarações de variáveis ​​não inicializadas são consideradas indefinidas (versões antigas podem realmente conter dados de programas anteriores).
samis 03/02
5
"Mas isso é realmente um bug (que pode até ser corrigido no ECMAScript 6)" - fonte?
Gajus 31/01
26

Qual é a diferença entre null e undefined ??

Uma propriedade quando não possui definição é indefinida. null é um objeto. Seu tipo é objeto. null é um valor especial que significa "nenhum valor. undefined não é um objeto, seu tipo é indefinido.

Você pode declarar uma variável, defini-la como nula e o comportamento é idêntico, exceto que você verá "nulo" impresso versus "indefinido". Você pode até comparar uma variável indefinida como nula ou vice-versa, e a condição será verdadeira:

 undefined == null
 null == undefined

Consulte Diferença de JavaScript entre nulo e indefinido para obter mais detalhes.

e com sua nova edição sim

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

ao testar se o objeto é falso, ambos apenas atendem à condição ao testar se falso , mas não quando verdadeiro

Verifique aqui: Pegcha Javascript

TStamper
fonte
4
Você deve usar ===, então indefinido == null: D!
olliej
1
Preste atenção à última parte, está incorreto ver a minha resposta;)
kentaromiura
6
! object não é o mesmo que "object == null" ... Na verdade, são bem diferentes. ! object retornará true se o objeto for 0, uma string vazia, Boolean false, undefined ou null.
James
3
Null é realmente um objeto? O primeiro link que você forneceu verifica nulo por typeof, mas typeof (nulo) é avaliado como 'objeto' devido a um erro de design de idioma.
C4il
2
nullnão é um objeto. O typeof null == 'object';retorno é verdadeiro devido a um erro que não pode ser corrigido no JavaScript (atualmente, mas pode mudar no futuro).
Mohamad
21

Primeira parte da pergunta:

Por que null é considerado um objeto em JavaScript?

É um erro de design do JavaScript que eles não podem corrigir agora. Deveria ter sido do tipo nulo, não do tipo objeto, ou não possuir nenhum. Requer uma verificação extra (às vezes esquecida) ao detectar objetos reais e é fonte de bugs.

Segunda parte da pergunta:

Está verificando


if (object == null)
Do something

o mesmo que

if (!object)
Do something

As duas verificações são sempre falsas, exceto:

  • O objeto é indefinido ou nulo: ambos são verdadeiros.

  • O objeto é primitivo e 0, ""ou falso: primeiro verifica falso, segundo verdadeiro.

Se o objeto não é um primitivo, mas um objeto real, como new Number(0), new String(""), ou new Boolean(false), então ambas as verificações são falsas.

Portanto, se 'objeto' for interpretado como um Objeto real, as duas verificações serão sempre as mesmas. Se primitivas forem permitidas, as verificações serão diferentes para 0 "", e false.

Em casos como esse object==null, os resultados não óbvios podem ser uma fonte de erros. O uso de ==nunca é recomendado, use em ===vez disso.

Terceira parte da pergunta:

E também:

Qual é a diferença entre nulo e indefinido?

No JavaScript, uma diferença é que nulo é do tipo objeto e indefinido é do tipo indefinido.

Em JavaScript, null==undefinedé verdadeiro e considerado igual se o tipo for ignorado. Por que eles decidiram isso, mas 0 ""e falso não são iguais, eu não sei. Parece ser uma opinião arbitrária.

Em JavaScript, isso null===undefinednão é verdade, pois o tipo deve ser o mesmo ===.

Na realidade, nulo e indefinido são idênticos, pois ambos representam a inexistência. O mesmo acontece com 0, e ""também nesse caso, e talvez nos contêineres vazios []e {}. Muitos tipos do mesmo nada são uma receita para bugs. Um tipo ou nenhum é melhor. Eu tentaria usar o mínimo possível.

'false', 'true' e '!' Há outro pacote de worms que pode ser simplificado, por exemplo, if(!x)e por if(x)si só são suficientes, você não precisa de verdadeiro e falso.

Um declarado var xé do tipo indefinido se nenhum valor for fornecido, mas deve ser o mesmo que se x nunca foi declarado. Outra fonte de erro é um contêiner vazio. Portanto, é melhor declarar e defini-lo juntos, como var x=1.

As pessoas estão girando e girando em círculos tentando descobrir todos esses tipos diferentes de nada, mas é tudo a mesma coisa em roupas diferentes e complicadas. A realidade é

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

E talvez todos devam lançar exceções.

Anon
fonte
8
Ótima resposta, mas vai um pouco longe demais com []: " Na realidade, nulo e indefinido são idênticos ... e talvez os contêineres vazios [] e {}. " Você provavelmente poderia me convencer a pensar que {} deveria ser sabor nulo, mas a minha impressão é que não deveria. Mas, de maneira menos controversa, é compreensível que uma matriz vazia []tenha uma .push()função , portanto não há um bom argumento para [] ser nulo. US $ 0,02.
Ruffin
11
var x = null;

x é definido como nulo

y não está definido; // porque eu não o defini

if (!x)

nulo é avaliado como falso

Chad Grant
fonte
8

Uma maneira de entender nulo e indefinido é entender onde cada um ocorre.

Espere um valor de retorno nulo nas seguintes situações:

  • Métodos que consultam o DOM

    console.log(window.document.getElementById("nonExistentElement"));
    //Prints: null
  • Respostas JSON recebidas de uma solicitação Ajax


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

  • Nova funcionalidade que está em um estado de fluxo. O seguinte retorna nulo:


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

       // But this returns undefined:

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

Todos os outros casos de inexistência são denotados por indefinidos (conforme observado por @Axel). Cada uma das seguintes impressões é "indefinida":

    var uninitalised;
    console.log(uninitalised);

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

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

    missingParam();

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

Obviamente, se você decidir escrever var unitialised = null; ou retorne nulo de um método, você terá nulos ocorrendo em outras situações. Mas isso deve ser bastante óbvio.

Um terceiro caso é quando você deseja acessar uma variável, mas nem sabe se ela foi declarada. Nesse caso, use typeof para evitar um erro de referência:

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

Em resumo, verifique se há nulo ao manipular o DOM, lidar com o Ajax ou usar determinados recursos do ECMAScript 5. Para todos os outros casos, é seguro verificar indefinidamente com igualdade estrita:

if(value === undefined){
  // stuff
}
Noel Abrahams
fonte
8

Comparação de muitas verificações nulas diferentes no 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

Gráfico de comparação de verificação nula do JavaScript

Aaron Hoffman
fonte
1
faz "var myUndefined;" definir a variável (como uma variável conhecida com tipo desconhecido)?
Qi Fan
6

nulo e indefinido são falsos para igualdade de valor (nulo == indefinido): ambos são recolhidos para booleano false. Eles não são o mesmo objeto (nulo! == indefinido).

undefined é uma propriedade do objeto global ("janela" nos navegadores), mas é um tipo primitivo e não um objeto em si. É o valor padrão para variáveis ​​e funções não inicializadas que terminam sem uma declaração de retorno.

null é uma instância de Object. null é usado para métodos DOM que retornam objetos de coleção para indicar um resultado vazio, que fornece um valor falso sem indicar um erro.

Anônimo
fonte
5

Algumas precisões:

nulo e indefinido são dois valores diferentes. Um representa a ausência de um valor para um nome e o outro representa a ausência de um nome.


O que acontece de uma maneira ifé a seguinte if( o ):

A expressão entre parênteses o é avaliada e, em seguida, ifinicia-se a coação do valor da expressão entre parênteses - no nosso caso o.

Os valores de falsidade (que serão coagidos a falsos) no JavaScript são: '', nulo, indefinido, 0 e falso .

Laurent Villeneuve
fonte
5

Para adicionar à resposta de Qual é a diferença entre undefinedenull , no JavaScript Definitive Guide 6th Edition, p.41 nesta página :

Você pode considerar undefineda nullausência de valor no nível do sistema, inesperada ou semelhante a erro e representar a ausência de valor no nível do programa, normal ou prevista. Se você precisar atribuir um desses valores a uma variável ou propriedade ou passar um desses valores para uma função, nullé quase sempre a escolha certa.

falta de polaridade
fonte
3

nullé um objeto. Seu tipo é nulo. undefinednão é um objeto; seu tipo é indefinido.

Vikas
fonte
11
errado - ambos nulle undefinedsão valores primitivos - typeof null === 'object'é um erro de linguagem porque:Object(null) !== null
Christoph
Não, não é. O Object () lança o trabalho dessa maneira, consulte ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - 15.2.2.1 new Object ([value]) ... 8. (O valor do argumento não foi fornecido ou seu tipo era Nulo ou Indefinido.) Crie um novo objeto ECMAScript nativo. A propriedade [[Prototype]] do objeto recém-construído é definida como o objeto Prototype Object. A propriedade [[Class]] do objeto recém-construído é definida como "Objeto". O objeto recém-construído não possui propriedade [[Value]]. Retorne o objeto nativo recém-criado.
Kartomiura
3
@Christoph: Quero dizer, você está certo. null deve ser um tipo, o que quero dizer é que você não pode verificá-lo dessa maneira porque: alert (new Object ()! == new Object ()); / * true, nova istance não é a mesma istance / alert (Object (null) .constructor == {} .constructor); / true como em spec / alert (Object (null) .prototype == {} .prototype); / true como em spec / alert (instância nula de Object); / Obviamente falsa, meios nulos não instanciado * / Mas, basicamente, é um XD bug especificações ver: uselesspickles.com/blog/2006/06/12/... e javascript.crockford.com/remedial.html
kentaromiura
2

A função a seguir mostra por que e é capaz de resolver a diferença:

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

Se você ligar

test();

Você está recebendo

Indefinido

nulo

As primeiras console.log(...)tentativas para obter myPropertya partir myObjenquanto ele ainda não está definida - por isso, recebe de volta "indefinido". Depois de atribuir nulo a ele, o segundo console.log(...)retorna obviamente "nulo" porque myPropertyexiste, mas tem o valornull atribuído a ele.

Para poder consultar essa diferença, o JavaScript tem nulle undefined: Enquanto nullé - assim como em outros idiomas, um objeto undefinednão pode ser um objeto porque não há instância (mesmo que não seja uma nullinstância) disponível.


fonte
2

Por exemplo window.someWeirdProperty é indefinido, então

"window.someWeirdProperty === null" avalia como falso enquanto

"window.someWeirdProperty === undefined" avalia como verdadeiro.

Além disso checkif if (!o)não é o mesmo que a verificação if (o == null)para oser false.

Piotr Findeisen
fonte
Você pode elaborar a diferença entre as duas condições
rahul
leia minha resposta, ele significa que se o é igual a 0, falso ou "" o valor booleano é falso: var undef, various = [0, "", null, false, undef]; for (var obj em vários) {alert (! obj); // 4 vezes falso no IE, 5 no FF;)}
kentaromiura 29/04/09
2

A outra coisa divertida sobre o nulo, em comparação com o indefinido, é que ele pode ser incrementado.

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

Isso é útil para definir valores numéricos padrão para contadores. Quantas vezes você definiu uma variável para -1 em sua declaração?

Tim Scollick
fonte
2

Em Javascript null não é um objecttipo, é umprimitave tipo.

Qual é a diferença? Indefinido refere-se a um ponteiro que não foi definido. Nulo refere-se ao ponteiro nulo, por exemplo, algo definiu manualmente uma variável para ser do tiponull

AnonDCX
fonte
2

Veja isso:

   <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
ZPKSoft
fonte
1

De "Os Princípios do Javascript Orientado a Objetos", de Nicholas C. Zakas

Mas por que um objeto quando o tipo é nulo? (De fato, isso foi reconhecido como um erro pelo TC39, o comitê que cria e mantém o JavaScript. Você pode considerar que nulo é um ponteiro de objeto vazio, tornando o "objeto" um valor de retorno lógico, mas isso ainda é confuso.)

Zakas, Nicholas C. (07-02-2014). Os princípios do JavaScript orientado a objetos (Locais 226-227 do Kindle). Sem Starch Press. Edição Kindle.

Dito isto:

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 indefinido:

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.
Felix
fonte
1

A melhor maneira de pensar em 'nulo' é lembrar como o conceito semelhante é usado nos bancos de dados, onde indica que um campo não contém "nenhum valor".

  • Sim, o valor do item é conhecido; ele é 'definido'. Ele tem sido inicializado.
  • O valor do item é: "não há valor".

Essa é uma técnica muito útil para escrever programas que são mais facilmente depurados. Uma variável 'indefinida' pode ser o resultado de um bug ... (como você saberia?) ... mas se a variável contiver o valor 'null', você saberá que "alguém, em algum lugar deste programa, defina-o como 'null.' "Portanto, sugiro que, quando você precisar se livrar do valor de uma variável, não" exclua "... defina-o como 'null.' O valor antigo ficará órfão e em breve será coletado do lixo; o novo valor é "não há valor (agora)". Nos dois casos, o estado da variável é certo: "obviamente, deliberadamente, foi assim".

Mike Robinson
fonte
1
  1. Indefinido significa que uma variável foi declarada, mas não foi atribuído nenhum valor, enquanto Null pode ser atribuído a uma variável que representa "nenhum valor" (Null é um operador de atribuição)

Indefinido é um tipo em si, enquanto Nulo é um objeto.

3.Javascript pode inicializar qualquer variável não atribuída como indefinida, mas nunca pode definir o valor de uma variável como nulo. Isso deve ser feito programaticamente.

the_unknown_spirit
fonte