Obtenir le nom de l'objet ou de la classe


204

Existe-t-il une solution pour obtenir le nom de fonction d'un objet?

function alertClassOrObject (o) {
   window.alert(o.objectName); //"myObj" OR "myClass" as a String
}

function myClass () {
   this.foo = function () {
       alertClassOrObject(this);
   }
}

var myObj = new myClass();
myObj.foo();

for (var k in this) {...}- il n'y a aucune information sur le classNameou ObjectName. Est-il possible d'en obtenir un?


Vous voudrez peut-être voir ceci: stackoverflow.com/questions/789675/…
Sudhir Bastakoti

Réponses:


350

Obtenez la fonction constructeur de votre objet, puis inspectez sa propriété name .

myObj.constructor.name

Renvoie "maClasse".


175
Il faut se méfier! Si vous réduisez le JavaScript, le nom du constructeur changera.
dB.

34
Pratique, mais il y a une autre mise en garde: si votre objet a une chaîne prototype (à part Object), vous obtiendrez le nom du premier maillon de cette chaîne, pas le nom du constructeur utilisé pour créer l'objet. Prenons l'exemple suivant: function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.namepuis revient de façon inattendue 'Daddy', non 'Me'.
mklement0

7
Il convient également de savoir que la propriété de nom n'est pas prise en charge dans <IE9
Jason

10
Et cela renvoie une chaîne vide, si elle est utilisée sur des objets déclarés par la variable: var Foo = function() {};.
Aleksandr Makov

3
La console Chrome sait quelque chose que vous ne savez pas: > myclass=(function(){}); new myclassimprimemyclass {}
Hugh Allen

26

Exemple:

function Foo () { console.log('Foo function'); }
var Bar = function () { console.log('Bar function'); };
var Abc = function Xyz() { console.log('Abc function'); };

var f = new Foo();
var b = new Bar();
var a = new Abc();

console.log('f', f.constructor.name); // -> "Foo"
console.log('b', b.constructor.name); // -> "Function"
console.log('a', a.constructor.name); // -> "Xyz"


ressemble à l'utilisation du modèle de module révélateur, vous obtiendrez toujours "Object". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent

5

Si vous utilisez le standard IIFE (par exemple avec TypeScript)

var Zamboch;
(function (_Zamboch) {
    (function (Web) {
        (function (Common) {
            var App = (function () {
                function App() {
                }
                App.prototype.hello = function () {
                    console.log('Hello App');
                };
                return App;
            })();
            Common.App = App;
        })(Web.Common || (Web.Common = {}));
        var Common = Web.Common;
    })(_Zamboch.Web || (_Zamboch.Web = {}));
    var Web = _Zamboch.Web;
})(Zamboch || (Zamboch = {}));

vous pouvez annoter les prototypes dès le départ avec

setupReflection(Zamboch, 'Zamboch', 'Zamboch');

puis utilisez les champs _fullname et _classname.

var app=new Zamboch.Web.Common.App();
console.log(app._fullname);

fonction d'annotation ici:

function setupReflection(ns, fullname, name) {
    // I have only classes and namespaces starting with capital letter
    if (name[0] >= 'A' && name[0] &lt;= 'Z') {
        var type = typeof ns;
        if (type == 'object') {
            ns._refmark = ns._refmark || 0;
            ns._fullname = fullname;
            var keys = Object.keys(ns);
            if (keys.length != ns._refmark) {
                // set marker to avoid recusion, just in case 
                ns._refmark = keys.length;
                for (var nested in ns) {
                    var nestedvalue = ns[nested];
                    setupReflection(nestedvalue, fullname + '.' + nested, nested);
                }
            }
        } else if (type == 'function' && ns.prototype) {
            ns._fullname = fullname;
            ns._classname = name;
            ns.prototype._fullname = fullname;
            ns.prototype._classname = name;
        }
    }
}

JsFiddle


4

Comme cela a déjà été répondu, je voulais juste souligner les différences d'approche pour obtenir le constructeur d'un objet en JavaScript. Il existe une différence entre le constructeur et le nom réel de l'objet / classe. Si ce qui suit ajoute à la complexité de votre décision, alors peut-être que vous recherchez instanceof. Ou peut-être que vous devriez vous demander "Pourquoi est-ce que je fais ça? Est-ce vraiment ce que j'essaie de résoudre?"

Remarques:

Le obj.constructor.namen'est pas disponible sur les anciens navigateurs. La correspondance (\w+)doit satisfaire les classes de style ES6.

Code:

var what = function(obj) {
  return obj.toString().match(/ (\w+)/)[1];
};

var p;

// Normal obj with constructor.
function Entity() {}
p = new Entity();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));

// Obj with prototype overriden.
function Player() { console.warn('Player constructor called.'); }
Player.prototype = new Entity();
p = new Player();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));

// Obj with constructor property overriden.
function OtherPlayer() { console.warn('OtherPlayer constructor called.'); }
OtherPlayer.constructor = new Player();
p = new OtherPlayer();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));

// Anonymous function obj.
p = new Function("");
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));

// No constructor here.
p = {};
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));

// ES6 class.
class NPC { 
  constructor() {
  }
}
p = new NPC();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));

// ES6 class extended
class Boss extends NPC {
  constructor() {
    super();
  }
}
p = new Boss();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));

Résultat:

entrez la description de l'image ici

Code: https://jsbin.com/wikiji/edit?js,console


3

J'étais confronté à une difficulté similaire et aucune des solutions présentées ici n'était optimale pour ce sur quoi je travaillais. Ce que j'avais, c'était une série de fonctions pour afficher le contenu dans un modal et j'essayais de le refactoriser sous une définition d'objet unique faisant les fonctions, les méthodes de la classe. Le problème est survenu lorsque j'ai trouvé qu'une des méthodes créait des boutons de navigation à l'intérieur du modal eux-mêmes qui utilisaient un onClick pour l'une des fonctions - maintenant un objet de la classe. J'ai envisagé (et envisage toujours) d'autres méthodes pour gérer ces boutons de navigation, mais j'ai pu trouver le nom de variable pour la classe elle-même en balayant les variables définies dans la fenêtre parent. Ce que j'ai fait, c'est chercher quoi que ce soit correspondant à l'instance de ma classe, et au cas où il pourrait y en avoir plus d'un,

var myClass = function(varName)
{
    this.instanceName = ((varName != null) && (typeof(varName) == 'string') && (varName != '')) ? varName : null;

    /**
     * caching autosweep of window to try to find this instance's variable name
     **/
    this.getInstanceName = function() {
        if(this.instanceName == null)
        {
            for(z in window) {
                if((window[z] instanceof myClass) && (window[z].uniqueProperty === this.uniqueProperty)) {
                    this.instanceName = z;
                    break;
                }
            }
        }
        return this.instanceName;
    }
}

1

Essaye ça:

var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];

1
Y a-t-il des cas où cela serait plus précis que obj.constructor.name? Je ne vois tout simplement aucune raison à cette complexité.
JHH

1

Tout ce dont nous avons besoin:

  1. Envelopper une constante dans une fonction (où le nom de la fonction est égal au nom de l'objet que nous voulons obtenir)
  2. Utiliser les fonctions fléchées à l'intérieur de l'objet

console.clear();
function App(){ // name of my constant is App
  return {
  a: {
    b: {
      c: ()=>{ // very important here, use arrow function 
        console.log(this.constructor.name)
      }
    }
  }
}
}
const obj = new App(); // usage

obj.a.b.c(); // App

// usage with react props etc, 
// For instance, we want to pass this callback to some component

const myComponent = {};
myComponent.customProps = obj.a.b.c;
myComponent.customProps(); // App

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.