Est-il un JavaScript équivalent de Java class.getName()
?
Réponses
Trop de publicités?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. :)
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.
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