2010-03-25 3 views
24

Comme par http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf, JavaScript dispose de 6 types: undefined, null, boolean, string, number et object.types JavaScript

var und; 
console.log(typeof und); // <-- undefined 

var n = null; 
console.log(typeof n); // <--- **object**! 

var b = true; 
console.log(typeof b); // <-- boolean 

var str = "myString" 
console.log(typeof str); // <-- string 

var int = 10; 
console.log(typeof int); // <-- number 

var obj = {} 
console.log(typeof obj); // <-- object 

Question 1:

Pourquoi est nul de type object au lieu de null?

Question 2:

Qu'en est-il des fonctions?

var f = function() {}; 
console.log(typeof f); // <-- function 

variable f a le type de function. Pourquoi n'est-il pas spécifié dans la spécification en tant que type distinct?

Merci,

+3

+1 pour creuser dans la spécification, la recherche de l'illumination globale. –

Répondre

13

A propos typeof null == 'object', c'est une erreur qui vient depuis les premiers jours, et malheureusement cette erreur va rester avec nous pendant longtemps, il était too late à fixer dans le ECMAScript 5 Spécifications Edition. A propos des fonctions 10, ils sont juste des objets, mais ils ont une propriété interne spéciale appelée [[Call]] qui est utilisée en interne lorsqu'une fonction est appelée.

L'opérateur typeof fait la distinction entre les objets simples et les fonctions simplement en vérifiant si l'objet possède cette propriété interne.

5

C'est parce que typeof est définie pour renvoyer « objet » si l'entrée est null et retour « fonction » si l'entrée est appelable. (Voir 11.4.3 L'opérateur typeof.)

Je ne sais pas pourquoi la norme est définie comme ceci (and Crockford said it's wrong). Peut-être la rétrocompatibilité.

0

Réponse à la question 1:

Une propriété, quand il n'a pas de définition, est définie. La raison null est un objet est de sorte qu'une propriété peut exister sans valeur mais avoir encore une définition.

+1

En fait, je pense que c'est un peu trompeur. Il y a une différence entre indéfini et non déclaré. Par exemple, 'var x' mettra une propriété nommée' x' dans la portée courante, mais sa valeur sera 'undefined'. Avant que cela ne se produise, 'x' lui-même est indéfini, et essayer de l'utiliser se traduira par un' ReferenceError'. – bcherry

+1

Aussi, 'null' n'est * pas * un objet, c'est une * valeur primitive *, malheureusement l'opérateur' typeof' est juste faux ... – CMS

0

typeof null === "object" parce que la spécification le dit, mais c'est une erreur de la toute première version de JavaScript. (comme KennyTM dit ci-dessus). Parce que, sans try/catch, il n'y a pas d'autre moyen fiable et infaillible de déterminer si quelque chose est appelable. En utilisant f.constructor === Functionpourrait de travail, mais je pense que ce n'est pas garanti.

0

Pour être complet, notez que la façon la plus pratique actuelle pour vérifier les informations de type est quelque chose comme ceci:

var typeInfo = Object.prototype.toString.call(yourObject); 

Cela vous donne une chaîne qui ressemble à « [objet quelque chose] », où « quelque chose » est un nom de type.

+0

'Object.prototype.toString.call (undefined)' me donne '[ objet Fenêtre] 'dans Firefox o_O. – kennytm

+0

KennyTM: C'est parce que lorsque 'null' ou' undefined' sont utilisés comme premier argument de 'call' ou' apply', le contexte (le mot-clé 'this') à l'intérieur de la fonction invoquée sera défini sur l'objet global. – CMS

+0

Droit - si vous utilisez cette technique, vous feriez probablement un test explicite === pour un premier non défini – Pointy

0

est une valeur spéciale, ce n'est pas faux, ce n'est pas 0, ou la chaîne vide ou NaN ou indéfini. Null est ce que vous obtenez lorsque vous recherchez un objet qui n'est pas là - pas une propriété non définie d'un objet, mais la chose elle-même. Un paragraphe avec un textNode renverra null pour les nœuds nextSibling, une regexp qui ne correspond pas retourne null au lieu du tableau et ainsi de suite.

peut-être qu'il devrait avoir son propre type, mais alors il commence à être quelque chose, un quelque chose avec un type, au lieu de l'absence d'un objet.

0

Il existe également également un modèle Array.prototype.

  • Object.prototype
  • Array.prototype
  • Function.prototype
  • Number.prototype
  • String.prototype
  • Boolean.prototype

Crockford dit de ne pas utiliser :

  • nouveau numéro()
  • new String()
  • new Boolean()