value instanceof Constructor
est la même chose que Constructor.prototype.isPrototypeOf(value)
et vérifient tous les deux la chaîne [[Prototype]]- de value
pour les occurrences d'un objet spécifique.
Les chaînes de caractères et les nombres sont valeurs primitives Ils ne sont pas des objets et n'ont donc pas de [[Prototype]]. Ils ne fonctionneront donc que si vous les intégrez dans des objets normaux (ce que l'on appelle "boxing" en Java).
Aussi, comme vous l'avez remarqué, String(value)
y new String(value)
font des choses différentes : Si vous appelez les fonctions de construction des types intégrés sans utiliser l'attribut new
ils essaient de convertir ('cast') l'argument au type spécifique. Si vous utilisez l'opérateur new
ils créent un objet de type "wrapper".
new String(value)
est à peu près équivalent à Object(String(value))
qui se comporte de la même manière que new Object(String(value))
.
Un peu plus sur les types en JavaScript : L'ECMA-262 définit les types primitifs suivants : Indéfini , Nulle , Booléen , Numéro y Chaîne de caractères . En outre, il existe le type Objet pour les choses qui ont des propriétés.
Par exemple, les fonctions sont de type Objet (ils ont simplement une propriété spéciale appelée [[Appel]]), et null
est une valeur primitive de type Nulle . Cela signifie que le résultat de la typeof
ne renvoie pas vraiment le type d'une valeur...
De plus, les objets JavaScript ont une autre propriété appelée [[Class]]. Vous pouvez l'obtenir via Object.prototype.toString.call(value)
(ceci retournera '[object
Classname
]'
). Les tableaux et les fonctions sont du type Objet mais leurs classes sont Array y Fonction .
Le test pour la classe d'un objet donné ci-dessus fonctionne lorsque instanceof
échoue (par exemple, lorsque les objets sont transmis entre les limites de la fenêtre/image et ne partagent pas les mêmes prototypes).
Vous pouvez également consulter la version améliorée de l'application suivante typeof
:
function typeOf(value) {
var type = typeof value;
switch(type) {
case 'object':
return value === null ? 'null' : Object.prototype.toString.call(value).
match(/^\[object (.*)\]$/)[1]
case 'function':
return 'Function';
default:
return type;
}
}
Pour les primitives, il retournera leur type en minuscule pour les objets, il renvoie leur classe en cas titre .
Exemples :
-
Pour les primitives de type Numéro (par exemple 5
), il retournera 'number'
pour les objets enveloppes de classe Numéro (par exemple new Number(5)
), il retournera 'Number'
;
-
Pour les fonctions, il renverra 'Function'
.
Si vous ne voulez pas faire la distinction entre les valeurs primitives et les objets enveloppants (pour une raison quelconque, probablement mauvaise), utilisez typeOf(...).toLowerCase()
.
Les bogues connus sont certaines fonctions intégrées dans IE, qui sont considérées comme étant 'Object'
et une valeur de retour de 'unknown'
lorsqu'il est utilisé avec certains objets COM+.
0 votes
Vous devez utiliser
Number.prototype.isPrototypeOf(inp)
- votre façon de faire fonctionnerait aussi si elle était faite correctement :inp.constructor === Number
; elle pourrait échouer, carconstructor
est juste une propriété du prototype et peut être écrasé !0 votes
Je ne suis pas sûr de comprendre ce que vous voulez dire par "peut être écrasé". Cela ne signifie pas que je peux écraser le constructeur avec un autre constructeur (j'ai essayé). D'ailleurs, Number.prototype.isPrototypeOf(4) renvoie false, donc je ne peux pas l'utiliser pour vérifier le type des valeurs primitives, n'est-ce pas ?
0 votes
C'était le but recherché (primitive !== primitive enveloppée) ! La vérification des constructeurs est dangereuse à cause de
obj['constructor'] = ???
fonctionne ! Je vous suggère d'utiliser montypeOf()
pour traiter les primitives et les primitives enveloppées de la même manière, utilisez la fonctionif(typeOf(x).toLowerCase() === 'string')
0 votes
D'après mon expérience, le fait d'assigner quoi que ce soit à Obj.constructor ne change pas son constructeur. En fait, une telle affectation semble ne rien faire du tout. ('hellowrld').constructor = Number renvoie toujours String avec getType.
0 votes
J'ai essayé votre typeOf bien sûr et oui, cela a fonctionné pour les types primitifs. Je voulais une fonction pour tous les types, primitifs ou non. Je vais essayer de casser getType, si je n'y arrive pas, je suppose que c'est utilisable.
0 votes
Avez-vous testé votre fonction getType() ? Elle retourne toujours 'undefined', sauf si l'argument est en réalité
undefined
- alors, il retourne 'null' ! Vérifiez également joost.zeekat.nl/constructeurs-considérés-mildly-confusing.html pour savoir commentconstructor
est résolu !0 votes
Oui, je l'ai testé et oui, ça n'a pas marché (ça dépend du navigateur). Il ne fonctionne qu'avec jscript (donc : IE), pas dans les autres navigateurs, à ma grande surprise bien sûr). J'ai fait un test sur les navigateurs, réécrit la fonction et réédité cette question.
0 votes
Ça s'appelle une abstraction fuyante. JS a en fait 2 types d'objets, un type est une union de types étiquetée (google VARIANT pour une utilisation de JScript), et un autre étant une union de types étiquetée qui est spécifiquement un objet (en JScript, étant IDispatch/IDispatchEx). Puisque seuls les objets sont des "instances", instanceof n'essaie pas de faire un travail supplémentaire en déterminant au cas par cas ou en consultant des tables pour trouver un type compatible capable de le gérer. Je pense que c'est une boîte de Pandore sans réponse correcte connue au moment de la conception, donc ils ont choisi l'approche la plus honnête/flexible.
0 votes
Bien que la solution simple soit
Object(4) instanceof Number
réussit. de mêmenull instanceof Object
échoue, alors queObject(null) instanceof Object
réussit. Étant donné une correction aussi simple, je peux comprendre pourquoi il est raisonnable de ne pas implémenter l'enveloppement automatique dans Object dans instanceof. Cela rend typeof juste un peu plus rapide.