Por que typeof nulo é "objeto"?


241

Estou lendo o capítulo 4 'Javascript profissional para desenvolvedores da Web' e ele diz que os cinco tipos de primitivas são: indefinido, nulo, booleano, número e sequência.

Se nullé um primitivo, por que typeof(null)retorna "object"?

Isso não significa que isso nullé passado por referência (suponho que todos os objetos sejam passados ​​por referência), tornando-o NÃO um primitivo?


50
Resposta: Porque a especificação diz isso. Isso geralmente é considerado um erro.
SLaks 15/09/13

5
Observe que typeof é um operador, não uma função (e, de fato, você pode omitir os parênteses em torno do que vem depois), portanto, não faz sentido falar sobre a passagem por referência aqui. O livro "JavaScript: The Good Parts" na verdade menciona o fato de que typeof null === 'objeto' na seção A.6 do apêndice A intitulado 'Awful Parts'.
John Sonderson

5
Eu acho que gostaria de ler 'Awful Parts' hah
austinheiman

1
erro enorme, insondável! :)
Alexander Mills

2
Então, o que devemos usar em vez de typeof para verificar o tipo de valor que uma variável está mantendo? Eu adoraria saber o que é entre (boolean, corda, número, matriz, objeto, função, símbolo, null, indefinido, NaN)
Costa

Respostas:


219

Na página MDN sobre o comportamento do typeofoperador :

null

// Isso permanece desde o início do JavaScript
typeof null === 'objeto';

Na primeira implementação do JavaScript, os valores do JavaScript foram representados como uma tag de tipo e um valor. A tag de tipo para objetos era 0. nullfoi representada como o ponteiro NULL (0x00 na maioria das plataformas). Conseqüentemente, null tinha 0 como tag de tipo, portanto, o typeofvalor de retorno "object" . ( referência )

Uma correção foi proposta para ECMAScript (por meio de uma inclusão), mas foi rejeitada . Teria resultado typeof null === 'null'.


137
É uma pena que esta mudança não, pelo menos, fazê-lo em modo estrito ...
Ingo Bürk

As pessoas têm sido aproveitando a peculiaridade, e muitos código lá fora, vai ter de ser alterada sempre que tal não foi rejeitada, eu acho
Fria Cerberus

Faz mais sentido para as poucas pessoas vivas que desejam que isso mude seu código, do que o resto dos desenvolvedores pelo resto do tempo precisa aprender. Só porque uma pessoa ainda não existe, não significa necessariamente que não importa, apenas significa que está indefesa.
Seph Reed

não faz sentido por que as pessoas usariam isso como uma verificação nula de qualquer maneira. Não faz sentido intuitivo, então por que eles usariam? Agora a alteração não pode ser adicionada devido a códigos incorretos.
Emobe

69

Se nullé um primitivo, por que typeof(null)retorna "object"?

Porque as especificações dizem isso .

11.4.3 O typeofoperador

A produção UnaryExpression : typeof UnaryExpression é avaliada da seguinte maneira:

  1. Seja val o resultado da avaliação da UnaryExpression .
  2. Se Tipo ( val ) for Referência ,
       a. Se IsUnresolvableReference ( val ) for verdadeiro , retorne " undefined".
       b. Vamos Val ser GetValue ( val ).
  3. Retorne uma String determinada pelo Tipo ( val ) de acordo com a Tabela 20.

insira a descrição da imagem aqui


O @ Peter não typeofdiz nada sobre se você pode ou não chamar métodos em alguma coisa.
Matt Bola

2
Que eu saiba, você pode chamar métodos em qualquer coisa que não seja nulle undefined.
Matt Bola

4
@peter você não pode chamar métodos em uma primitiva de string, mas, felizmente, as primitivas de string (e primitivas de número e primitivas booleanas) são implícita e automaticamente "encaixotadas automaticamente" nos wrappers String, Number e Boolean quando você usa uma das primitivas com uma propriedade operador de referência ( .ou [ ]).
Pointy

28

Como foi apontado, a especificação diz isso. Mas como a implementação do JavaScript é anterior à gravação da especificação do ECMAScript, e a especificação teve o cuidado de não corrigir os pontos fracos da implementação inicial, ainda há uma pergunta legítima sobre por que isso foi feito dessa maneira em primeiro lugar. Douglas Crockford chama isso de um erro . Kiro Risk acha que meio que faz sentido :

O raciocínio por trás disso é que null, em contraste com undefined, foi (e ainda é) frequentemente usado onde os objetos aparecem. Em outras palavras, nullé frequentemente usado para significar uma referência vazia a um objeto. Quando Brendan Eich criou o JavaScript, ele seguiu o mesmo paradigma, e fazia sentido (sem dúvida) retornar "objeto". De fato, a especificação ECMAScript define nullcomo o valor primitivo que representa a ausência intencional de qualquer valor de objeto (ECMA-262, 11.4.11).


3
Como não consigo encontrar agora o vídeo, publicarei isso apenas para pessoas curiosas e sem nenhuma referência: Crockford explicou como um valor zero na resolução de um tipo de nulo apontava para o elemento indexado zero na matriz de tipos, por isso estava claro desenvolvimento bug que os caras da Microsoft acidentalmente propagado quando decompiling e recompilar JS para o seu navegador
Axel Costas Pena

6

Do livro YDKJS

Este é um bug de longa data no JS, mas provavelmente nunca será corrigido. Muito código na Web depende do bug e, portanto, corrigi-lo causaria muito mais erros!


1
não confie em tudo que está escrito em um livro. Eu realmente amo esse livro, no entanto, não posso considerar esse erro, porque a especificação ECMA para JavaScript declara que o tipo de nulo deve ser um objeto.
andreasonny83

4

Se nullé um primitivo, por que typeof(null)retornar " object"?

em resumo: é um bug no ECMAScript, e o tipo deve ser null

referência: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null


1
Em nenhum lugar na sua referência ele afirma que é um bug.
user2867288

1
E em nenhum lugar da especificação ele diz que typeof deve retornar qualquer coisa, exceto "indefinido", "objeto", "booleano", "número", "string", "função" e "símbolo" (ECMAScript 2015)
Brad Kent

1

No JavaScript nulo é "nada". É suposto ser algo que não existe. Infelizmente, em JavaScript, o tipo de dados null é um objeto. Você pode considerar um erro no JavaScript que typeof null é um objeto. Deve ser nulo.


0

No JavaScript, typeof null é 'object', o que sugere incorretamente que null é um objeto. Este é um erro que infelizmente não pode ser corrigido, porque quebraria o código existente.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.