Dapatkan nama objek atau kelas

204

Apakah ada solusi untuk mendapatkan nama fungsi suatu objek?

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) {...}- tidak ada informasi tentang classNameatau ObjectName. Apakah mungkin untuk mendapatkan salah satunya?

TJR
sumber
Anda mungkin ingin melihat ini: stackoverflow.com/questions/789675/…
Sudhir Bastakoti

Jawaban:

349

Dapatkan fungsi konstruktor objek Anda dan kemudian periksa properti namanya .

myObj.constructor.name

Mengembalikan "myClass".

Oleg V. Volkov
sumber
175
Awas! Jika Anda mengecilkan JavaScript, nama konstruktor akan berubah.
dB.
34
Berguna, tetapi ada peringatan lain: jika objek Anda memiliki rantai prototipe (selain dari Object), Anda akan mendapatkan nama tautan pertama dalam rantai itu, bukan nama konstruktor yang digunakan untuk membuat objek. Ambil contoh berikut: function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.namelalu tiba-tiba kembali 'Daddy', tidak 'Me'.
mklement0
7
Juga patut diketahui bahwa properti nama tidak didukung di <IE9
Jason
10
Dan ini akan kembali string kosong, jika digunakan pada objek dinyatakan melalui variabel: var Foo = function() {};.
Aleksandr Makov
3
Konsol Chrome tahu sesuatu yang tidak Anda ketahui: > myclass=(function(){}); new myclasscetakanmyclass {}
Hugh Allen
26

Contoh:

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
sumber
Sepertinya ketika menggunakan pola modul pengungkapan, Anda akan selalu mendapatkan "Objek". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent
5

Jika Anda menggunakan IIFE standar (misalnya dengan 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 = {}));

Anda dapat membuat anotasi prototipe di muka dengan

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

dan kemudian gunakan bidang _fullname dan _classname.

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

fungsi anotasi di sini:

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
sumber
4

Karena ini sudah dijawab, saya hanya ingin menunjukkan perbedaan dalam pendekatan untuk mendapatkan konstruktor dari objek dalam JavaScript. Ada perbedaan antara konstruktor dan objek / nama kelas yang sebenarnya. Jika yang berikut menambah kompleksitas keputusan Anda, mungkin Anda sedang mencari instanceof. Atau mungkin Anda harus bertanya pada diri sendiri, "Mengapa saya melakukan ini? Apakah ini benar-benar yang saya coba selesaikan?"

Catatan:

Tidak obj.constructor.nametersedia di browser lama. Pencocokan (\w+)harus memenuhi kelas gaya ES6.

Kode:

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

Hasil:

masukkan deskripsi gambar di sini

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

Șerban Ghiță
sumber
3

Saya menghadapi kesulitan yang sama dan tidak ada solusi yang disajikan di sini yang optimal untuk apa yang saya kerjakan. Apa yang saya miliki adalah serangkaian fungsi untuk menampilkan konten dalam modal dan saya mencoba untuk membuatnya kembali di bawah definisi objek tunggal yang membuat fungsi, metode kelas. Masalahnya muncul ketika saya menemukan salah satu metode membuat beberapa tombol nav di dalam modal sendiri yang menggunakan onClick ke salah satu fungsi - sekarang menjadi objek kelas. Saya telah mempertimbangkan (dan masih mempertimbangkan) metode lain untuk menangani tombol nav ini, tetapi saya dapat menemukan nama variabel untuk kelas itu sendiri dengan menyapu variabel yang didefinisikan di jendela induk. Apa yang saya lakukan adalah mencari sesuatu yang cocok dengan 'instanceof' kelas saya, dan kalau-kalau mungkin ada lebih dari satu,

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

Coba ini:

var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];
Mohamed Karray
sumber
1
Apakah ada kasus di mana ini akan lebih akurat daripada obj.constructor.name? Saya hanya tidak melihat alasan untuk kompleksitas ini.
JHH
1

Semua yang kita butuhkan:

  1. Bungkus konstanta dalam suatu fungsi (di mana nama fungsi sama dengan nama objek yang ingin kita dapatkan)
  2. Gunakan fungsi panah di dalam objek

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
sumber