web-dev-qa-db-fra.com

Comment récupérer le nom du constructeur en JavaScript?

Supposons le programme suivant:

var C = function() { };
x = new C();

L'expression x instanceof C donne True, donc x doit savoir qu'il a été construit par la fonction C. Est-il possible de récupérer le nom C directement à partir de x?

(Dans mon problème, j'ai une hiérarchie de prototypes implémentant des signaux possibles dans mon application. Je dois accéder au type de signal qui doit être équivalent au constructeur utilisé pour créer ce signal.)

27
Marc

Sur Chrome (7.0.544.0 dev), si je le fais:

function C() { }

var x = new C();

console.log(x.constructor.name);

il affiche 'C' ... mais si C est défini comme une fonction non nommée telle que vous l'avez, il imprimera une chaîne vide à la place.

Si j'imprime x.constructor, il imprime la même chose que si j'imprimais C dans le code que vous avez. L'opérateur instanceof n'a qu'à comparer ces deux valeurs pour voir qu'elles sont égales pour pouvoir renvoyer true.

29
sje397

Ce code obtiendra le nom du constructeur, tant que ce n'est pas une fonction anonyme:

obj.constructor.toString().match(/function (\w*)/)[1];

Pourquoi auriez-vous besoin du nom de la classe? Supposons que vous souhaitiez enregistrer et restaurer des instances de classe via JSON. Vous pouvez stocker le nom de la classe dans une propriété "type", puis utiliser une fonction de résolution dans JSON.parse pour restaurer les objets. (Voir l'exemple de code sur cette page ).

Donc, en théorie, vous pourriez utiliser le code ci-dessus pour créer un sérialiseur généralisé pouvant gérer n'importe quelle instance de classe, mais l'analyse des chaînes de fonctions est très inefficace. Cette surcharge peut être évitée en imposant explicitement le type à toutes les classes que vous allez stocker:

function Foo() {}
Foo.prototype.type = 'Foo';

Cela semble stupide et redondant, c'est pourquoi j'ai commencé à chercher implicitement à obtenir le nom de la classe. Mais à la fin je dois céder: il n'y a pas de solution acceptable dans JS :-(

9
phatmann

Non. Vous pouvez utiliser x.constructor pour obtenir une référence directe à C, mais il s'agit d'une fonction anonyme, il n'y a donc aucun moyen d'obtenir son nom.

Si c'était défini comme suit:

function C() { };
x = new C();

Ensuite, il serait possible d'utiliser x.constructor.toString() et d'analyser le nom de la fonction à partir de la chaîne renvoyée. Certains navigateurs supportent également x.constructor.name[1].

[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name

3
Andy E

Vous pouvez aussi déclarer votre classe comme ceci:

var C = function C() { };

Maintenant, votre constructeur de classe C n'est plus une fonction anonyme, ce qui signifie que vous pouvez faire:

x = new C();    

console.log(x.constructor.name); // output: C
1
Wilt

Ce code qui a besoin de connaître le constructeur peut-il accéder à la fonction constructeur elle-même? Si c'est le cas, vous pouvez simplement faire cette instance.

Il semble que vous ayez besoin de le savoir par son nom. Cela semble dangereux. Quelqu'un peut créer un autre constructeur qui porte le même nom et qui passera (sauf si c'est ce que vous voulez, bien sûr).

0
RichN