Obtener el nombre del objeto o clase

Resuelto TJR asked hace 12 años • 10 respuestas

¿Existe alguna solución para obtener el nombre de la función de un objeto?

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) {...}- no hay información sobre el classNameo ObjectName. ¿Es posible conseguir uno de ellos?

TJR avatar Apr 25 '12 18:04 TJR
Aceptado

Obtenga la función constructora de su objeto y luego inspeccione su propiedad de nombre .

myObj.constructor.name

Devuelve "miClase".

Oleg V. Volkov avatar Apr 25 '2012 11:04 Oleg V. Volkov

Ejemplo:

function Foo () { console.log('Foo function'); }
var f = new Foo();
console.log('f', f.constructor.name); // -> "Foo"

var Bar = function () { console.log('Anonymous function (as Bar)'); };
var b = new Bar();
console.log('b', b.constructor.name); // -> "Bar"

var Abc = function Xyz() { console.log('Xyz function (as Abc)'); };
var a = new Abc();
console.log('a', a.constructor.name); // -> "Xyz"

class Clazz { constructor() { console.log('Clazz class'); } }
var c = new Clazz();
console.log('c', c.constructor.name); // -> "Clazz"

var otherClass = class Cla2 { constructor() { console.log('Cla2 class (as otherClass)'); } }
var c2 = new otherClass();
console.log('c2', c2.constructor.name); // -> "Cla2"
Expandir fragmento

Ejemplo fijo:

function alertClassOrObject (o) {
   // ::::::: Fixed line
   console.log(o.constructor.name); //"myObj" OR "myClass" as a String
   // ::::::: Fixed line
}

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

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

Eduardo Cuomo avatar Nov 21 '2013 13:11 Eduardo Cuomo

Como esto ya fue respondido, solo quería señalar las diferencias en los enfoques para obtener el constructor de un objeto en JavaScript. Existe una diferencia entre el constructor y el nombre real del objeto/clase. Si lo siguiente aumenta la complejidad de su decisión, entonces tal vez esté buscando instanceof. O tal vez deberías preguntarte "¿Por qué estoy haciendo esto? ¿Es esto realmente lo que estoy tratando de resolver?"

Notas:

No obj.constructor.nameestá disponible en navegadores más antiguos. La coincidencia (\w+)debe satisfacer las clases de estilo ES6.

Código:

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

Resultado:

ingrese la descripción de la imagen aquí

Código: https://jsbin.com/wikiji/edit?js,console

Actualización: 04 de diciembre de 2023

Para aquellos que necesitan obtener el nombre de la clase en IE6 e IE8, obj.constructorexiste pero namela propiedad no existe. Entonces necesitas llamar what(obj.constructor).

ingrese la descripción de la imagen aquí

Șerban Ghiță avatar Oct 25 '2016 21:10 Șerban Ghiță

Si usa IIFE estándar (por ejemplo 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 = {}));

podrías anotar los prototipos por adelantado con

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

y luego use los campos _fullname y _classname.

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

Función de anotación aquí:

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

Pavel Savara avatar Apr 04 '2014 12:04 Pavel Savara