Nesnenin veya sınıfın adını alma


204

Bir nesnenin işlev adını almak için herhangi bir çözüm var mı?

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) {...}- classNameveya hakkında bilgi yoktur ObjectName. Onlardan birini almak mümkün mü?


Yanıtlar:


349

Nesnenizin yapıcı işlevini alın ve sonra name özelliğini inceleyin .

myObj.constructor.name

"Sınıfım" ı döndürür.


175
Dikkat! JavaScript'i küçültüyorsanız, kurucunun adı değişecektir.
dB.

34
Kullanışlı, ancak başka bir uyarı var: nesnenizde bir prototip zinciri varsa (bir kenara Object), nesneyi oluşturmak için kullanılan kurucunun adını değil, o zincirdeki ilk bağlantının adını alırsınız . Aşağıdaki örneği ele alalım: function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.namesonra beklenmedik bir şekilde geri döner 'Daddy', değil 'Me'.
mklement0

7
Ayrıca name özelliğinin <IE9
Jason

10
Bu, değişken: ile bildirilen nesnelerde kullanılırsa boş dize döndürür var Foo = function() {};.
Aleksandr Makov

3
Chrome konsolu bilmediğiniz bir şey biliyor: > myclass=(function(){}); new myclassyazdırıyormyclass {}
Hugh Allen

26

Misal:

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"


ifşa eden modül modelini kullanırken her zaman "Nesne" elde edersiniz. function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent

5

Standart IIFE kullanıyorsanız (örneğin TypeScript ile)

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 = {}));

prototipleri önceden

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

ve _fullname ve _classname alanlarını kullanın.

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

açıklama fonksiyonu burada:

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

Bu daha önce yanıtlandığı için, JavaScript'te bir nesnenin yapıcısını alma yaklaşımlarındaki farklılıklara dikkat çekmek istedim. Yapıcı ile gerçek nesne / sınıf adı arasında bir fark vardır. Aşağıdakiler kararınızın karmaşıklığına katkıda bulunuyorsa, belki de aradığınız şeydir instanceof. Ya da belki kendinize "Bunu neden yapıyorum? Çözmeye çalıştığım şey bu mu?"

Notlar:

obj.constructor.nameEski tarayıcılarda kullanılamaz. Eşleştirme (\w+), ES6 stil sınıflarını karşılamalıdır.

Kod:

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

Sonuç:

resim açıklamasını buraya girin

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


3

Benzer bir güçlükle karşı karşıya kaldım ve burada sunulan çözümlerin hiçbiri üzerinde çalıştığım şeyler için uygun değildi. Elimde bir modda içerik görüntülemek için bir dizi işlev vardı ve sınıfın işlevlerini, yöntemlerini yaparak tek bir nesne tanımı altında onu yeniden düzenlemeye çalışıyordum. Sorun, yöntemlerden birinin, artık sınıfın bir nesnesi olan bir onClick işlevini kullanan bir modda bazı nav-düğmeleri oluşturduğunu bulduğumda geldi. Bu nav düğmelerini işlemek için diğer yöntemleri düşündüm (ve hala düşünüyoruz), ancak üst pencerede tanımlanan değişkenleri süpürerek sınıfın kendisi için değişken adını bulabildim. Yaptığım şey, sınıfımın "örneğiyle" eşleşen bir şey aramaktı ve birden fazla olması durumunda,

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

Bunu dene:

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

1
Bunun obj.constructor.name'den daha doğru olacağı herhangi bir durum var mı? Bu karmaşıklığın hiçbir sebebini görmüyorum.
JHH

1

Tek ihtiyacımız olan:

  1. Bir işleve bir sabit sarma (işlevin adı almak istediğimiz nesnenin adına eşittir)
  2. Nesnenin içindeki ok işlevlerini kullanma

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.