Ottieni il nome dell'oggetto o della classe


204

Esiste una soluzione per ottenere il nome della funzione di un oggetto?

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) {...}- non ci sono informazioni sul classNameo ObjectName. È possibile ottenerne uno?


Si potrebbe desiderare di vedere questo: stackoverflow.com/questions/789675/...
Sudhir Bastakoti

Risposte:


350

Ottieni la funzione di costruzione dell'oggetto e quindi controlla la proprietà del nome .

myObj.constructor.name

Restituisce "myClass".


175
Attenzione! Se stai minimizzando JavaScript, il nome del costruttore cambierà.
dB.

34
Pratico, ma c'è un altro avvertimento: se il tuo oggetto ha una catena prototipo (a parte Object), otterrai il nome del primo anello in quella catena, non il nome del costruttore usato per creare l'oggetto. Prendiamo il seguente esempio: function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.namepoi ritorna inaspettatamente 'Daddy', no 'Me'.
mklement0

7
Vale anche la pena sapere che la proprietà name non è supportata in <IE9
Jason il

10
E questo restituirà una stringa vuota, se utilizzato su oggetti dichiarati tramite la variabile: var Foo = function() {};.
Aleksandr Makov,

3
La console Chrome sa qualcosa che non > myclass=(function(){}); new myclassconosci : stampamyclass {}
Hugh Allen,

26

Esempio:

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"


sembra che quando usi lo schema del modulo rivelatore, otterrai sempre "Oggetto". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent,

5

Se si utilizza IIFE standard (ad esempio con 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 = {}));

potresti annotare in anticipo i prototipi con

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

e quindi utilizzare i campi _fullname e _classname.

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

funzione di annotazione qui:

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

Dato che era già stata data una risposta, volevo solo sottolineare le differenze negli approcci per ottenere il costruttore di un oggetto in JavaScript. C'è una differenza tra il costruttore e l'effettivo nome oggetto / classe. Se quanto segue aumenta la complessità della tua decisione, forse stai cercando instanceof. O forse dovresti chiederti "Perché sto facendo questo? È davvero quello che sto cercando di risolvere?"

Appunti:

Non obj.constructor.nameè disponibile nei browser meno recenti. La corrispondenza (\w+)dovrebbe soddisfare le classi di stile ES6.

Codice:

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

Risultato:

inserisci qui la descrizione dell'immagine

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


3

Stavo affrontando una difficoltà simile e nessuna delle soluzioni presentate qui era ottimale per quello su cui stavo lavorando. Quello che avevo era una serie di funzioni per visualizzare il contenuto in un modale e stavo provando a rifattorizzarlo in un'unica definizione di oggetto creando le funzioni, i metodi della classe. Il problema si presentò quando trovai uno dei metodi che creava alcuni pulsanti di navigazione all'interno del modale stesso che utilizzava un onClick per una delle funzioni - ora un oggetto della classe. Ho considerato (e sto ancora considerando) altri metodi per gestire questi pulsanti di navigazione, ma sono stato in grado di trovare il nome della variabile per la classe stessa spazzando le variabili definite nella finestra principale. Quello che ho fatto è stato cercare qualcosa che corrispondesse all'istanza della mia classe e, nel caso in cui ce ne potesse essere più di uno,

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

Prova questo:

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

1
C'è un caso in cui questo sarebbe più preciso di obj.constructor.name? Non vedo alcun motivo per questa complessità.
JHH il

1

Tutto ciò di cui abbiamo bisogno:

  1. Avvolgere una costante in una funzione (dove il nome della funzione è uguale al nome dell'oggetto che vogliamo ottenere)
  2. Utilizzare le funzioni freccia all'interno dell'oggetto

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.