Pourquoi typeof est-il un «objet» nul?

242

Je lis le chapitre 4 «Javascript professionnel pour les développeurs Web» et il me dit que les cinq types de primitives sont: non défini, nul, booléen, nombre et chaîne.

Si nullest une primitive, pourquoi typeof(null)revient-il "object"?

Cela ne signifierait-il pas que ce processus nullest transmis par référence (je suppose ici que tous les objets sont transmis par référence), ce qui en fait PAS un primitif?

thetrystero
la source
50
Réponse: Parce que la spécification le dit. Ceci est généralement considéré comme une erreur.
SLaks le
5
Notez que typeof est un opérateur, pas une fonction (et en fait, vous pouvez omettre les parenthèses autour de ce qui vient après), il n'est donc pas logique de parler de passer par référence ici. Le livre "JavaScript: The Good Parts" mentionne en fait le fait que typeof null === 'object' dans la section A.6 de l'annexe A intitulée 'Awful Parts'.
John Sonderson
5
Je pense que je voudrais lire 'Awful Parts' hah
austinheiman
1
énorme erreur, insondable! :)
Alexander Mills
2
Alors, que devrions-nous utiliser au lieu de typeof pour vérifier le type de valeur qu'une variable contient? J'aimerais savoir de quoi il s'agit (booléen, chaîne, nombre, tableau, objet, fonction, symbole, null, non défini, NaN)
Costa

Réponses:

219

À partir de la page MDN sur le comportement de l' typeofopérateur :

null

// Cela existe depuis le début de JavaScript
typeof null === 'objet';

Dans la première implémentation de JavaScript, les valeurs JavaScript étaient représentées sous la forme d'une balise de type et d'une valeur. La balise de type pour les objets était 0. nullétait représenté comme le pointeur NULL (0x00 sur la plupart des plates-formes). Par conséquent, null avait 0 comme balise de type, d'où la typeofvaleur de retour "objet" . ( référence )

Un correctif a été proposé pour ECMAScript (via un opt-in), mais a été rejeté . Cela aurait abouti typeof null === 'null'.

Deepak Ingole
la source
138
C'est dommage que ce changement n'ait pas au moins fait passer en mode strict…
Ingo Bürk
Les gens ont profité de la bizarrerie, et de nombreux codes devront être modifiés si cela n'était pas rejeté, je suppose
Cold Cerberus
Il est plus logique pour les quelques personnes vivantes qui souhaitent que cela change leur code, que pour le reste des développeurs d'avoir à l'apprendre. Le fait qu'une personne n'existe pas encore ne signifie pas nécessairement qu'elle n'a pas d'importance, cela signifie simplement qu'elle est sans défense.
Seph Reed
n'a pas de sens pourquoi les gens utiliseraient cela comme un contrôle nul de toute façon. Cela n'a pas de sens intuitif, alors pourquoi l'utiliseraient-ils? Maintenant, le changement ne peut pas être ajouté en raison d'un mauvais codage.
Emobe
69

Si nullest une primitive, pourquoi typeof(null)revient-il "object"?

Parce que la spécification le dit .

11.4.3 L' typeofopérateur

La production UnaryExpression : typeof UnaryExpression est évaluée comme suit:

  1. Soit val le résultat de l'évaluation de UnaryExpression .
  2. Si Type ( val ) est Référence , alors
       a. Si IsUnresolvableReference ( val ) est vrai , retournez " undefined".
       b. Laissez val être GetValue ( val ).
  3. Renvoie une chaîne déterminée par Type ( val ) conformément au tableau 20.

entrez la description de l'image ici

Matt Ball
la source
@peter typeofne vous dit pas si vous pouvez ou non appeler des méthodes sur quelque chose.
Matt Ball
2
À ma connaissance, vous pouvez appeler des méthodes sur autre chose que nullet undefined.
Matt Ball
4
@peter vous ne pouvez pas appeler de méthodes sur une primitive de chaîne, mais heureusement, les primitives de chaîne (et les primitives de nombre et les primitives booléennes) sont implicitement et automatiquement "encadrées automatiquement" dans les encapsuleurs de chaîne, de nombre et booléens lorsque vous utilisez l'une des primitives avec une propriété opérateur de référence ( .ou [ ]).
Pointy
28

Comme cela a été souligné, la spécification le dit. Mais comme l'implémentation de JavaScript est antérieure à l'écriture de la spécification ECMAScript et que la spécification a pris soin de ne pas corriger les faiblesses de l'implémentation initiale, il y a encore une question légitime sur la raison pour laquelle cela a été fait de cette façon en premier lieu. Douglas Crockford appelle cela une erreur . Kiro Risk pense que c'est un peu logique :

Le raisonnement derrière cela est que null, contrairement à undefined, était (et est toujours) souvent utilisé là où les objets apparaissent. En d'autres termes, nullest souvent utilisé pour signifier une référence vide à un objet. Lorsque Brendan Eich a créé JavaScript, il a suivi le même paradigme, et il était logique (sans doute) de renvoyer "objet". En fait, la spécification ECMAScript définit nullcomme la valeur primitive qui représente l'absence intentionnelle de toute valeur d'objet (ECMA-262, 11.4.11).

chryss
la source
3
Comme je ne trouve pas maintenant la vidéo, je posterai ceci juste pour les personnes curieuses et sans aucune référence: Crockford a expliqué comment une valeur nulle lors de la résolution du type de null pointait vers l'élément indexé zéro sur le tableau des types, donc c'était clair développement d'un bug que les gars de Microsoft ont accidentellement propagé lors de la décompilation et de la recompilation de JS pour leur navigateur
Áxel Costas Pena
6

Extrait du livre YDKJS

Il s'agit d'un bogue de longue date dans JS, mais qui ne sera probablement jamais corrigé. Trop de code sur le Web repose sur le bogue et le corriger entraînerait donc beaucoup plus de bogues!

Faisal Ashfaq
la source
1
ne croyez pas que tout est écrit dans un livre. J'aime vraiment ce livre, cependant, je ne peux pas considérer cela comme un bug car la spécification ECMA pour JavaScript stipule que le type de null doit être un objet.
andreasonny83
4

Si nullest une primitive, pourquoi typeof(null)retourne " object"?

en bref: c'est un bogue dans ECMAScript, et le type devrait être null

référence: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

jobin
la source
1
Nulle part dans votre référence n'indique qu'il s'agit d'un bogue.
user2867288
1
Et nulle part dans la spécification, il n'est dit que typeof devrait retourner autre chose que "non défini", "objet", "booléen", "numéro", "chaîne", "fonction" et "symbole" (ECMAScript 2015)
Brad Kent
1

En JavaScript, null est "rien". C'est censé être quelque chose qui n'existe pas. Malheureusement, en JavaScript, le type de données null est un objet. Vous pouvez considérer cela comme un bogue en JavaScript que typeof null est un objet. Elle devrait être nulle.

Farzana Khan
la source
0

En JavaScript, typeof null est 'object', ce qui suggère à tort que null est un objet. Il s'agit d'un bug qui ne peut malheureusement pas être corrigé, car il casserait le code existant.

Slim Coder
la source