1310 votes

Comment puis-je obtenir le nom d'un type de l'objet en JavaScript?

Est-il un JavaScript équivalent de Java class.getName()?

1668voto

Jason Bunting Points 27534

Voici un hack qui va faire ce que vous devez être conscient qu'il modifie le prototype de l'Objet, quelque chose que les gens désapprouvent généralement pour une bonne raison)

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

Maintenant, tous vos objets ont la fonction, getName(), qui sera de retour le nom du constructeur comme une chaîne de caractères. J'ai testé ce dans FF3 et IE7, je ne peux pas parler pour les autres implémentations.

Si vous ne voulez pas le faire, voici une discussion sur les différentes façons de déterminer les types en JavaScript...


J'ai récemment mis à jour la présente à être un peu plus exhaustif, mais il n'est guère que. Corrections de bienvenue...

À l'aide de l' constructor de la propriété...

Chaque objet a une valeur pour son constructor de la propriété, mais en fonction de comment cet objet a été construit ainsi que ce que vous voulez faire avec cette valeur, il peut ou peut ne pas être utile.

En règle générale, vous pouvez utiliser l' constructor propriété pour tester le type de l'objet comme suit:

var myArray = [1,2,3];
(myArray.constructor == Array); // true

Donc, qui fonctionne assez bien pour la plupart des besoins. Cela dit...

Mises en garde

Un exemple où il n'est pas aussi évident est l'utilisation de l'héritage multiple:

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

Aujourd'hui des choses ne fonctionnent pas comme vous pourriez vous attendre à:

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

Ainsi, vous pouvez obtenir des résultats inattendus si l'objet de votre test a un autre objet en tant que son prototype. Il y a des façons de contourner cela en dehors de la portée de cette discussion.

Il y a d'autres utilisations pour l' constructor de la propriété, certaines intéressantes, d'autres pas tellement; pour l'instant, nous n'allons pas plonger dans ces utilisations, car il n'est pas pertinent pour la présente discussion.

Ne travail de la croix-cadre et de la croix-fenêtre

À l'aide de .constructor pour le type de la vérification de la pause lorsque vous voulez vérifier le type d'objets issus de différents window objets, dire que d'un iframe ou une fenêtre pop-up. C'est parce qu'il y a une version différente de chaque type de base de constructeur dans chaque "fenêtre", c'est à dire

iframe.contentWindow.Array === Array // false

À l'aide de l' instanceof opérateur...

L' instanceof - opérateur est un moyen propre de l'objet de test de type de bien, mais a ses propres problèmes potentiels, tout comme l' constructor de la propriété.

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

Mais instanceof ne parvient pas à travailler pour des valeurs primitives

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

Une enveloppe est nécessaire autour de primitives pour instanceof de travail, par exemple

new Number(3) instanceof Number // true

C'est ironique parce que l' .constructor vérifier fonctionne très bien pour les primitives

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

Pourquoi deux points pour les 3? Parce que Javascript interprète le premier point comme séparateur décimal ;)

Ne travail de la croix-cadre et de la croix-fenêtre

instanceof permettra aussi de ne pas travailler dans différents windows, pour la même raison que le constructeur de la propriété vérifier.


À l'aide de l' name de la propriété de l' constructor de la propriété...

Ne fonctionne PAS dans <IE9

À l'aide de myObjectInstance.constructor.name vous donnera une chaîne de caractères contenant le nom du constructeur de la fonction utilisée, mais elle est subordonnée à la mise en garde à propos de la propriété constructeur qui ont été mentionnés précédemment.

Pour IE9 et au-dessus, vous pouvez singe-patch à l'appui:

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

À L'Aide De L'Objet.le prototype.toString

Il s'avère, comme ce post de détails, vous pouvez utiliser l'Objet.le prototype.toString - le faible niveau générique et la mise en œuvre de toString - pour obtenir le type pour tous les types intégrés

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

On pourrait écrire un court de fonction d'assistance tels que

function type(obj){
    return Object.prototype.toString.call(obj).slice(8, -1);
}

pour supprimer les fichiers inutiles et d'obtenir juste le nom du type

type('abc') // String

Toutefois, il sera de retour l '"Objet" pour tous les types définis par l'utilisateur.


Mises en garde pour tous les...

Tous ces éléments sont soumis à un potentiel problème, et c'est la question de savoir comment l'objet en question a été construit. Voici les différentes façons de construire des objets et les valeurs que les différentes méthodes de vérification de type sera de retour:

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

Bien que pas toutes les permutations sont présents dans cette série d'exemples, j'espère qu'il sont assez pour vous donner une idée sur la façon malpropre choses pourraient, selon vos besoins. Ne présumez de rien, si vous ne comprenez pas exactement ce que vous êtes après, vous pouvez vous retrouver avec un code de rupture où vous ne l'attendez pas à cause d'un manque de grokking les subtilités.

NOTE:

Discussion de l' typeof de l'opérateur qui peut sembler être un oubli flagrant, mais ce n'est pas vraiment utile pour aider à identifier si un objet est d'un type donné, car il est très simpliste. Comprendre d'où typeof est utile est importante, mais je ne suis pas actuellement l'impression que c'est terriblement pertinente à cette discussion. Mon esprit est ouvert au changement. :)

152voto

Ewen Cartwright Points 3280

Jason Bunting la réponse m'a laissé assez d'indices pour trouver ce dont j'avais besoin:

<<Object instance>>.constructor.name

Ainsi, par exemple, dans le morceau de code suivant:

function MyObject() {}
var myInstance = new MyObject();

myInstance.constructor.name reviendrait "MyObject".

102voto

Christian Points 12142

NE PAS UTILISER LE CONSTRUCTEUR DE PROPRIÉTÉ.

Lisez CECI en premier.

Le code correct est:

function get_type(thing){
    if(thing===null)return "[object Null]"; // special case
    return Object.prototype.toString.call(thing);
}

// example results:
get_type(null)                    - [object Null]
get_type(window)                  - [object Window]
get_type([])                      - [object Array]
get_type(['1'])                   - [object Array]
get_type({})                      - [object Object]
get_type(document)                - [object HTMLDocument]
get_type(document.getElementById) - [object Function]

NB: Selon les spécifications, cette fonction est le plus fiable entre les différents navigateurs.

28voto

ajax81 Points 3215

Une petite astuce que j'utilise:

function Square(){
    this.className = "Square";
    this.corners = 4;
}

var MySquare = new Square();
console.log(MySquare.className); // "Square"

19voto

Saul Points 10449

Mise à jour

Pour être précis, je pense que l'OP a demandé pour une fonction qui récupère le constructeur de nom pour un objet particulier. En termes de Javascript, object n'ont pas de type, mais est un type de et en elle-même. Cependant, les différents objets peuvent avoir différents constructeurs.

Object.prototype.getConstructorName = function () {
   var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
   var cname = str.match(/function\s(\w*)/)[1];
   var aliases = ["", "anonymous", "Anonymous"];
   return aliases.indexOf(cname) > -1 ? "Function" : cname;
}

new Array().getConstructorName();  // returns "Array"
(function () {})().getConstructorName(); // returns "Function"

 


Remarque: l'exemple ci-dessous est obsolète.

Un blog lié par Christian Sciberras contient un bon exemple sur la façon de le faire. À savoir, par l'extension de l'Objet prototype:

if (!Object.prototype.getClassName) {
    Object.prototype.getClassName = function () {
        return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
    }
}

var test = [1,2,3,4,5];

alert(test.getClassName()); // returns Array

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