¿Por qué es typeof nulo "objeto"?

242

Estoy leyendo 'Capítulo 4 de JavaScript profesional para desarrolladores web' y me dice que los cinco tipos de primitivas son: indefinido, nulo, booleano, número y cadena.

Si nulles un primitivo, ¿por qué typeof(null)regresa "object"?

¿No significa eso que nullse pasa por referencia (supongo que aquí todos los objetos se pasan por referencia), por lo que NO es primitivo?

thetrystero
fuente
50
Respuesta: Porque la especificación lo dice. Esto generalmente se considera un error.
SLaks
55
Tenga en cuenta que typeof es un operador, no una función (y, de hecho, puede omitir los paréntesis en torno a lo que viene después), por lo que no tiene sentido hablar de pasar por referencia aquí. El libro "JavaScript: The Good Parts" en realidad menciona el hecho de que typeof null === 'object' en la sección A.6 del apéndice A titulado 'Awful Parts'.
John Sonderson
55
Creo que me gustaría leer 'Awful Parts' hah
austinheiman
1
gran error, insondable! :)
Alexander Mills
2
Entonces, ¿qué deberíamos usar en lugar de typeof para verificar el tipo de valor que contiene una variable? Me encantaría saber qué hay entre (booleano, cadena, número, matriz, objeto, función, símbolo, nulo, indefinido, NaN)
Costa

Respuestas:

219

Desde la página MDN sobre el comportamiento del typeofoperador :

null

// Esto se mantiene desde el comienzo de JavaScript
typeof null === 'objeto';

En la primera implementación de JavaScript, los valores de JavaScript se representaban como una etiqueta de tipo y un valor. La etiqueta de tipo para los objetos era 0. nullse representaba como el puntero NULL (0x00 en la mayoría de las plataformas). En consecuencia, nulo tenía 0 como etiqueta de tipo, de ahí el typeofvalor de retorno "objeto" . ( referencia )

Se propuso una solución para ECMAScript (a través de una suscripción), pero se rechazó . Habría resultado en typeof null === 'null'.

Deepak Ingole
fuente
138
Es una pena que este cambio al menos no haya llegado al modo estricto ...
Ingo Bürk
La gente se ha aprovechado de la peculiaridad, y supongo que habrá que cambiar muchos códigos si esto no fue rechazado, supongo
Cold Cerberus
Tiene más sentido para las pocas personas vivas que desean que esto cambie su código, que el resto de desarrolladores por el resto del tiempo para tener que aprenderlo. El hecho de que una persona aún no exista no significa necesariamente que no importa, solo significa que está indefensa.
Seph Reed
no tiene sentido por qué la gente usaría esto como un cheque nulo de todos modos. No tiene sentido intuitivo, entonces, ¿por qué lo usarían? Ahora el cambio no se puede agregar debido a una mala codificación.
Emobe
69

Si nulles un primitivo, ¿por qué typeof(null)regresa "object"?

Porque la especificación lo dice .

11.4.3 El typeofoperador

La producción UnaryExpression : typeof UnaryExpression se evalúa de la siguiente manera:

  1. Sea val el resultado de evaluar UnaryExpression .
  2. Si Tipo ( val ) es Referencia , entonces
       a. Si IsUnresolvableReference ( val ) es verdadero , devuelve " undefined".
       si. Deje que val sea GetValue ( val ).
  3. Devuelve una Cadena determinada por Tipo ( val ) de acuerdo con la Tabla 20.

ingrese la descripción de la imagen aquí

Matt Ball
fuente
@peter no typeofle dice nada acerca de si puede o no llamar a métodos en algo.
Matt Ball
2
Que yo sepa, puede llamar a métodos en cualquier cosa que no sea nully undefined.
Matt Ball el
44
@peter no puede llamar a métodos en una cadena primitiva, pero afortunadamente las primitivas de cadena (y las primitivas de número y las primitivas booleanas) se "auto-encajonan" implícita y automáticamente en cadenas, números y envoltorios booleanos cuando usa una de las primitivas con una propiedad operador de referencia ( .o [ ]).
Puntiagudo
28

Como se ha señalado, la especificación lo dice. Pero dado que la implementación de JavaScript es anterior a la escritura de la especificación ECMAScript, y la especificación tuvo cuidado de no corregir las debilidades de la implementación inicial, todavía hay una pregunta legítima sobre por qué se hizo de esta manera en primer lugar. Douglas Crockford lo llama un error . Kiro Risk cree que tiene sentido :

El razonamiento detrás de esto es que null, en contraste con undefined, se usaba (y todavía se usa) a menudo donde aparecen los objetos. En otras palabras, a nullmenudo se usa para significar una referencia vacía a un objeto. Cuando Brendan Eich creó JavaScript, siguió el mismo paradigma, y ​​tenía sentido (posiblemente) devolver "objeto". De hecho, la especificación ECMAScript define nullcomo el valor primitivo que representa la ausencia intencional de cualquier valor de objeto (ECMA-262, 11.4.11).

chryss
fuente
3
Como no puedo encontrar ahora el video, lo publicaré solo para personas curiosas y sin ninguna referencia: Crockford explicó cómo un valor cero al resolver el tipo de nulo apuntaba al elemento indexado cero en la matriz de tipos, por lo que esto fue claro error de desarrollo que los chicos de Microsoft propagaron accidentalmente al descompilar y recompilar JS para su navegador
Áxel Costas Pena
6

Del libro YDKJS

Este es un error de larga data en JS, pero que probablemente nunca se solucionará. Demasiado código en la Web se basa en el error y, por lo tanto, solucionarlo provocaría muchos más errores.

Faisal Ashfaq
fuente
1
No confíes en que todo está escrito en un libro. Realmente amo ese libro, sin embargo, no puedo considerarlo un error porque la especificación de ECMA para JavaScript establece que el tipo de nulo debe ser un objeto.
andreasonny83
4

Si nulles un primitivo, ¿por qué typeof(null)devuelve " object"?

en resumen: es un error en ECMAScript, y el tipo debería ser null

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

Jobin
fuente
1
En ninguna parte de su referencia dice que es un error.
user2867288
1
Y en ninguna parte de la especificación dice que typeof debería devolver nada más que "indefinido", "objeto", "booleano", "número", "cadena", "función" y "símbolo" (ECMAScript 2015)
Brad Kent
1

En JavaScript nulo es "nada". Se supone que es algo que no existe. Desafortunadamente, en JavaScript, el tipo de datos nulo es un objeto. Puede considerarlo un error en JavaScript que typeof null es un objeto. Debería ser nulo.

Farzana Khan
fuente
0

En JavaScript, typeof null es 'objeto', lo que sugiere incorrectamente que nulo es un objeto. Este es un error y uno que desafortunadamente no se puede solucionar, porque rompería el código existente.

Codificador delgado
fuente