Obtener el nombre del objeto o clase

204

¿Hay 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 obtener uno de ellos?

TJR
fuente
Es posible que desee ver esto: stackoverflow.com/questions/789675/…
Sudhir Bastakoti

Respuestas:

350

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

myObj.constructor.name

Devuelve "myClass".

Oleg V. Volkov
fuente
175
¡Tener cuidado! Si está minimizando el JavaScript, el nombre del constructor cambiará.
dB.
34
Práctico, pero hay otra advertencia: si su objeto tiene una cadena de prototipo (aparte de Object), obtendrá el nombre del primer enlace en esa cadena, no el nombre del constructor utilizado para crear el objeto. Tomemos el siguiente ejemplo: function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.nameentonces inesperadamente regresa 'Daddy', no 'Me'.
mklement0
77
También vale la pena saber que la propiedad de nombre no es compatible con <IE9
Jason
10
Y esto devolverá una cadena vacía, si se utiliza en objetos declaró a través de variables: var Foo = function() {};.
Aleksandr Makov
3
La consola Chrome sabe algo que usted no sabe: > myclass=(function(){}); new myclassimpresionesmyclass {}
Hugh Allen
26

Ejemplo:

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
fuente
parece que cuando se utiliza el patrón de módulo revelador, siempre obtendrá "Objeto". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent
5

Si usa el estándar IIFE (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] &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
fuente
4

Como esto ya fue respondido, solo quería señalar las diferencias en los enfoques para obtener el constructor de un objeto en JavaScript. Hay una diferencia entre el constructor y el nombre real del objeto / clase. Si lo siguiente se suma a 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:

El obj.constructor.nameno está disponible en navegadores 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

Șerban Ghiță
fuente
3

Me enfrentaba a una dificultad similar y ninguna de las soluciones presentadas aquí era óptima para lo que estaba trabajando. Lo que tenía era una serie de funciones para mostrar contenido en un modo y estaba tratando de refactorizarlo bajo una única definición de objeto haciendo las funciones, métodos de la clase. El problema surgió cuando descubrí que uno de los métodos creaba algunos botones de navegación dentro del modal que usaban un onClick para una de las funciones, ahora un objeto de la clase. He considerado (y sigo considerando) otros métodos para manejar estos botones de navegación, pero pude encontrar el nombre de la variable para la clase barriendo las variables definidas en la ventana principal. Lo que hice fue buscar cualquier cosa que coincida con la 'instancia de' mi clase, y en caso de que haya más de una,

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
fuente
1

Prueba esto:

var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];
Mohamed Karray
fuente
1
¿Hay algún caso en el que esto sea más preciso que obj.constructor.name? Simplemente no veo ninguna razón para esta complejidad.
JHH
1

Todo lo que necesitamos:

  1. Envuelva una constante en una función (donde el nombre de la función es igual al nombre del objeto que queremos obtener)
  2. Usar funciones de flecha dentro del objeto

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
fuente