Ruft den Namen des Objekts oder der Klasse ab

204

Gibt es eine Lösung, um den Funktionsnamen eines Objekts zu erhalten?

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) {...}- Es gibt keine Informationen über das classNameoder ObjectName. Ist es möglich, einen von ihnen zu bekommen?

TJR
quelle
Vielleicht möchten Sie dies sehen: stackoverflow.com/questions/789675/…
Sudhir Bastakoti

Antworten:

348

Erhalten Sie Ihr Objekt der Konstruktor - Funktion und dann seine inspizieren Name - Eigenschaft.

myObj.constructor.name

Gibt "myClass" zurück.

Oleg V. Volkov
quelle
174
In acht nehmen! Wenn Sie das JavaScript minimieren, ändert sich der Name des Konstruktors.
dB.
34
Praktisch, aber es gibt einen anderen Nachteil: Wenn Ihr Objekt einen Prototyp hat Kette (abgesehen von Object), werden Sie die den Namen des bekommen erste Glied in dieser Kette, nicht der Name des Konstrukteurs verwendet , um das Objekt zu erstellen. Nehmen Sie das folgende Beispiel : function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.namekehrt dann unerwartet zurück 'Daddy', nicht 'Me'.
mklement0
7
Es ist auch erwähnenswert, dass die Eigenschaft name in <IE9
Jason,
9
Dies gibt eine leere Zeichenfolge zurück, wenn sie für Objekte verwendet wird, die über die Variable deklariert sind : var Foo = function() {};.
Aleksandr Makov
3
Die Chrome-Konsole weiß etwas, was Sie nicht wissen: > myclass=(function(){}); new myclassDruckemyclass {}
Hugh Allen
26

Beispiel:

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"

Eduardo Cuomo
quelle
Wenn Sie das aufschlussreiche Modulmuster verwenden, erhalten Sie immer "Objekt". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent
5

Wenn Sie Standard-IIFE verwenden (zum Beispiel mit 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 = {}));

Sie können die Prototypen im Voraus mit Anmerkungen versehen

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

Verwenden Sie dann die Felder _fullname und _classname.

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

Anmerkungsfunktion hier:

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

Pavel Savara
quelle
4

Da dies bereits beantwortet wurde, wollte ich nur auf die unterschiedlichen Ansätze beim Abrufen des Konstruktors eines Objekts in JavaScript hinweisen. Es gibt einen Unterschied zwischen dem Konstruktor und dem tatsächlichen Objekt- / Klassennamen. Wenn das Folgende die Komplexität Ihrer Entscheidung erhöht, suchen Sie vielleicht instanceof. Oder vielleicht sollten Sie sich fragen: "Warum mache ich das? Versucht ich das wirklich zu lösen?"

Anmerkungen:

Das obj.constructor.nameist in älteren Browsern nicht verfügbar. Das Matching (\w+)sollte den ES6-Stilklassen entsprechen.

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));

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

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

Șerban Ghiță
quelle
3

Ich hatte eine ähnliche Schwierigkeit und keine der hier vorgestellten Lösungen war optimal für das, woran ich arbeitete. Was ich hatte, war eine Reihe von Funktionen zum Anzeigen von Inhalten in einem Modal und ich versuchte, sie unter einer einzigen Objektdefinition umzugestalten, um die Funktionen und Methoden der Klasse zu erstellen. Das Problem trat auf, als ich feststellte, dass eine der Methoden einige Navigationsschaltflächen im Modal selbst erstellt hat, die einen onClick für eine der Funktionen verwendeten - jetzt ein Objekt der Klasse. Ich habe andere Methoden zur Behandlung dieser Navigationsschaltflächen in Betracht gezogen (und denke immer noch darüber nach), konnte jedoch den Variablennamen für die Klasse selbst finden, indem ich die im übergeordneten Fenster definierten Variablen durchsuchte. Was ich getan habe, war nach etwas zu suchen, das der 'Instanz' meiner Klasse entspricht, und falls es mehr als eine geben könnte,

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;
    }
}
Scott
quelle
1

Versuche dies:

var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];
Mohamed Karray
quelle
1
Gibt es einen Fall, in dem dies genauer wäre als obj.constructor.name? Ich sehe einfach keinen Grund für diese Komplexität.
JHH
1

Alles, was wir brauchen:

  1. Wickeln Sie eine Konstante in eine Funktion ein (wobei der Name der Funktion dem Namen des Objekts entspricht, das wir erhalten möchten).
  2. Verwenden Sie Pfeilfunktionen innerhalb des Objekts

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

Vladimir Bushma
quelle