939 votes

Comment obtenir la classe d'un objet JavaScript ?

J'ai créé un objet JavaScript, mais comment puis-je déterminer la classe de cet objet ?

Je veux quelque chose de similaire à la méthode Java .getClass() méthode.

13 votes

Par exemple, je crée une personne comme ceci : var p = new Person() ; J'ai un objet Personne appelé "p", comment puis-je utiliser "p" pour récupérer le nom de la classe : "Personne".

8 votes

0 votes

Mise à jour : Depuis ECMAScript 6, JavaScript ne dispose toujours pas d'une fonction class type. Il s'agit de fait ont un class mot-clé et class syntaxe permettant de créer des prototypes dans lesquels les méthodes peuvent plus facilement accéder aux super .

1278voto

earl Points 10428

Il n'y a pas d'équivalent exact de l'outil Java [getClass()](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#getClass()) en JavaScript. La plupart du temps, cela est dû au fait que JavaScript est une langage basé sur des prototypes par opposition à Java qui est un basé sur la classe un.

En fonction de ce dont vous avez besoin getClass() pour, il existe plusieurs options en JavaScript :

Quelques exemples :

function Foo() {}
var foo = new Foo();

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42

Note : si vous compilez votre code avec Uglify, il changera les noms de classes non globales. Pour éviter cela, Uglify a un --mangle que vous pouvez définir à false est d'utiliser gobler o grognement .

6 votes

Cela devrait probablement être func.prototype (oui, les fonctions sont des objets, mais le prototype n'est pertinente que pour les objets fonctionnels).

5 votes

Vous pourriez également mentionner instanceof / isPrototypeOf() et le non standard __proto__

14 votes

ES5 a en outre Object.getPrototypeOf()

382voto

chaiguy Points 7615
obj.constructor.name

est une méthode fiable dans les navigateurs modernes. Function.name a été officiellement ajouté à la norme dans ES6, ce qui en fait un moyen conforme aux normes d'obtenir la "classe" d'un objet JavaScript sous forme de chaîne. Si l'objet est instancié avec var obj = new MyClass() il renverra "MyClass".

Elle renvoie "Number" pour les nombres, "Array" pour les tableaux et "Function" pour les fonctions, etc. Il se comporte généralement comme prévu. Les seuls cas où elle échoue sont ceux où un objet est créé sans prototype, par l'intermédiaire de Object.create( null ) ou l'objet a été instancié à partir d'une fonction définie de manière anonyme (non nommée).

Notez également que si vous réduisez votre code, il n'est pas sûr de comparer avec des chaînes de caractères codées en dur. Par exemple, au lieu de vérifier si obj.constructor.name == "MyType" vérifiez plutôt obj.constructor.name == MyType.name . Ou simplement comparer les constructeurs eux-mêmes, mais cela ne fonctionnera pas au-delà des frontières du DOM, car il y a différentes instances de la fonction constructeur sur chaque DOM, donc faire une comparaison d'objets sur leurs constructeurs ne fonctionnera pas.

11 votes

Function.name ne fait pas (encore) partie de la norme JavaScript. Il est actuellement pris en charge par Chrome et Firefox, mais pas par IE(10).

0 votes

Object.create(something).constructor === something.constructor ce qui n'est pas tout à fait correct non plus. Ainsi, obj.constructor n'est pas fiable pour tous les objets créés avec Object.create, qu'ils aient ou non un prototype.

50 votes

Avertissement : ne comptez pas sur constructor.name si votre code est en train d'être minifié. Le nom de la fonction va changer arbitrairement.

37voto

Eli Grey Points 17553

Cette fonction getNativeClass() retourne "undefined" pour les valeurs non définies et "null" pour la nullité.
Pour toutes les autres valeurs, le CLASSNAME -est extrait de [object CLASSNAME] qui est le résultat de l'utilisation de Object.prototype.toString.call(value) .

getAnyClass() se comporte de la même manière que getNativeClass(), mais supporte également les constructeurs personnalisés

function getNativeClass(obj) {
  if (typeof obj === "undefined") return "undefined";
  if (obj === null) return "null";
  return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}

function getAnyClass(obj) {
  if (typeof obj === "undefined") return "undefined";
  if (obj === null) return "null";
  return obj.constructor.name;
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "null";

getAnyClass(new (function Foo(){})) === "Foo";
getAnyClass(new class Foo{}) === "Foo";

// etc...

1 votes

Object.prototype.getClass = function(){ utiliser 'this' au lieu d'obj serait agréable.

2 votes

Bien sûr, null et undefined ne seraient pas vérifiables puisque seul l'objet aurait la méthode getClass.

12 votes

Cela ne fonctionne que sur les objets natifs. Si vous avez une sorte d'héritage, vous obtiendrez toujours "Object" .

20voto

動靜能量 Points 33008

Pour obtenir la "pseudo classe", vous pouvez obtenir la fonction constructeur, par

obj.constructor

en supposant que le constructor est défini correctement lorsque vous faites l'héritage - qui est par quelque chose comme :

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

et ces deux lignes, ainsi que :

var woofie = new Dog()

fera woofie.constructor pointer vers Dog . Notez que Dog est une fonction constructeur, et est un Function objet. Mais vous pouvez faire if (woofie.constructor === Dog) { ... } .

Si vous voulez obtenir le nom de la classe sous forme de chaîne de caractères, j'ai trouvé que la méthode suivante fonctionnait bien :

http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}

Il se rend à la fonction constructeur, la convertit en chaîne de caractères et extrait le nom de la fonction constructeur.

Notez que obj.constructor.name aurait pu bien fonctionner, mais il n'est pas standard. Il fonctionne sur Chrome et Firefox, mais pas sur IE, y compris IE 9 ou IE 10 RTM.

0 votes

Tu gagnes des points pour le woofie.

15voto

CMS Points 315406

Vous pouvez obtenir une référence à la fonction du constructeur qui a créé l'objet en utilisant l'attribut propriété du constructeur :

function MyObject(){
}

var obj = new MyObject();
obj.constructor; // MyObject

Si vous devez confirmer le type d'un objet au moment de l'exécution, vous pouvez utiliser la fonction instanceof opérateur :

obj instanceof MyObject // true

0 votes

Ne renvoie-t-il pas la fonction constructeur elle-même, comme si vous pouviez l'appeler à nouveau et créer un nouvel objet de ce type ?

1 votes

@SparK Oui, mais vous pouvez toujours l'utiliser pour une comparaison tant que vous êtes sur le même DOM (vous comparez des objets fonctionnels). Cependant, il est préférable de transformer le constructeur en une chaîne de caractères et de la comparer, notamment parce que cela fonctionne au-delà des limites du DOM lorsque vous utilisez des iframes.

0 votes

Cette réponse renvoie la "classe" (ou au moins un handle de l'objet qui peut être utilisé pour créer une instance de la classe - ce qui est la même chose que "la classe"). Les réponses précédentes ont toutes retourné des chaînes de caractères, ce qui n'est pas la même chose que "l'objet classe" (pour ainsi dire).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X