2012-04-25 12 views
116

Gibt es eine Lösung, um den Funktionsnamen eines Objekts zu erhalten?Name des Objekts oder der Klasse

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 die className oder ObjectName. Ist es möglich, einen von ihnen zu bekommen?

+0

Man könnte dies sehen wollen: http://stackoverflow.com/questions/789675/how-to-get-class-objects-name-as-a-string-in-javascript –

+0

scheint richtig! Danke vielmals. Ich werde es versuchen! – TJR

Antwort

204

Holen Sie sich die constructor Funktion Ihres Objekts und überprüfen Sie dann die name Eigenschaft.

myObj.constructor.name 

Gibt "myClass" zurück.

+109

Vorsicht! Wenn Sie das JavaScript verkleinern, ändert sich der Name des Konstruktors. –

+25

Handlich, aber es gibt eine andere Einschränkung: Wenn Ihr Objekt einen Prototyp * Kette * (abgesehen von 'Object') hat, erhalten Sie den Namen des * ersten * Links in dieser Kette, nicht den Namen des Konstruktors, der zum Erstellen verwendet wird das Objekt. Nehmen Sie das folgende Beispiel: 'function Daddy() {}; Funktion Me() {}; Me.prototype = neuer Papa; ich = neues Ich; '. 'me.constructor.name' gibt dann unerwartet" Daddy "und nicht" Ich "zurück. – mklement0

+6

Auch wissenswert, dass die name-Eigenschaft in Jason

15

Beispiel:

function Foo() { ... } 
var Bar = function() { ... } 
var Abc = function Xyz() { ... } 

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

alert(f.constructor.name); // -> "Foo" 
alert(b.constructor.name); // -> "Function" 
alert(c.constructor.name); // -> "Xyz" 
+0

sieht aus wie bei der Verwendung des aufdeckenden Modulmusters, Sie erhalten immer "Objekt". 'Funktion Foo() {return {'foo': 'bar'}}; var f = new Foo(); ':( –

5

Wenn Sie Standard-IIFE verwenden (zum Beispiel mit Typoskript)

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 die Prototypen mit im Voraus mit Anmerkungen versehen konnte

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

und dann _fullname verwenden und _classname Felder.

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

Kommentierung Funktion hier:

function setupReflection(ns, fullname, name) { 
    // I have only classes and namespaces starting with capital letter 
    if (name[0] >= 'A' && name[0] <= '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

+0

Das ist zu schlau, sehr sehr nützlich. Danke. – engineforce

+22

Und f * cking hässlich. – maryisdead

4

Try this:

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

@ByteHamster Erzähle das Google? –

+0

@ByteHamster Zeiten ändern sich, und die angenommenen Antworten sind nicht immer die beste Antwort, ich sage nicht, dass dies einer dieser Fälle ist, aber was ist es für dich, wenn jemand eine neue Antwort auf eine alte Frage werfen möchte? – wallacer

2

Ich war hier präsentierte eine ähnliche Schwierigkeit und keine der Lösungen zugewandt waren optimal für das, was Ich habe daran gearbeitet. Was ich hatte, war eine Reihe von Funktionen, um Inhalt in einem Modal anzuzeigen, und ich versuchte, es unter einer einzigen Objektdefinition zu refactorieren, die die Funktionen, Methoden der Klasse macht. Das Problem trat auf, als ich eine der Methoden entdeckte, die einige Nav-Buttons innerhalb des Modales selbst erzeugten, die einen onClick zu einer der Funktionen verwendeten - jetzt ein Objekt der Klasse. Ich habe andere Methoden zur Handhabung dieser Navigationsschaltflächen in Erwägung gezogen (und denke immer noch darüber nach), aber ich konnte den Variablennamen für die Klasse selbst finden, indem ich die im übergeordneten Fenster definierten Variablen überstreiche. Was ich tat, war Suche nach etwas passend zu der ‚instanceof‘ meine Klasse, und im Fall könnte es mehr als eine sein, vergleichen ich eine bestimmte Eigenschaft, die für jede Instanz wahrscheinlich einzigartig war:

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; 
    } 
} 
4

Da diese wurde bereits beantwortet, ich wollte nur die Unterschiede in den Ansätzen auf den Konstruktor eines Objekts in JavaScript hinweisen. Es gibt einen Unterschied zwischen dem Konstruktor und dem tatsächlichen Objekt/Klassennamen. Wenn das Folgende zur Komplexität Ihrer Entscheidung beiträgt, suchen Sie vielleicht nach instanceof. Oder vielleicht solltest du dich selbst fragen: "Warum mache ich das? Ist das wirklich das, was ich versuche zu lösen?"

Hinweise:

Die obj.constructor.name ist auf älteren Browsern nicht zur Verfügung. Übereinstimmende (\w+) sollte ES6-Stilklassen erfüllen.

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:

enter image description here

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

Verwandte Themen