वस्तु या वर्ग का नाम जाना


204

क्या किसी वस्तु का फ़ंक्शन नाम प्राप्त करने के लिए कोई समाधान है?

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) {...}- के बारे में कोई जानकारी नहीं है classNameया ObjectName। क्या उनमें से एक को प्राप्त करना संभव है?


आप इसे देखना चाहते हो सकता है: stackoverflow.com/questions/789675/…
सुधीर बस्ताकोटी

जवाबों:


348

अपने ऑब्जेक्ट का निर्माता फ़ंक्शन प्राप्त करें और फिर उसकी नाम संपत्ति का निरीक्षण करें

myObj.constructor.name

"MyClass" देता है।


175
सावधान रहें! यदि आप जावास्क्रिप्ट को छोटा कर रहे हैं, तो कंस्ट्रक्टर का नाम बदल जाएगा।
डीबी।

34
हांडी, लेकिन एक और चेतावनी है: यदि आपकी वस्तु में एक प्रोटोटाइप श्रृंखला (एक तरफ से Object) है, तो आपको उस श्रृंखला में पहला लिंक का नाम मिलेगा , न कि उस ऑब्जेक्ट को बनाने के लिए उपयोग किए गए निर्माता का नाम। निम्नलिखित उदाहरण लें function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;:। me.constructor.nameफिर अप्रत्याशित रूप से लौटता है 'Daddy', नहीं 'Me'
mklement0

7
यह भी जानने योग्य है कि नाम की संपत्ति का समर्थन <IE9
जेसन

9
और यह रिक्त स्ट्रिंग को लौटाएगा, यदि चर के माध्यम से घोषित वस्तुओं पर उपयोग किया जाता है var Foo = function() {};:।
माकोव

3
क्रोम कंसोल आपको कुछ नहीं जानता है: > myclass=(function(){}); new myclassप्रिंटmyclass {}
ह्यू एलेन

26

उदाहरण:

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"


खुलासा मॉड्यूल पैटर्न का उपयोग करते समय, आपको हमेशा "ऑब्जेक्ट" मिलेगा। function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
ब्रैड केंट

5

यदि आप मानक IIFE का उपयोग करते हैं (उदाहरण के लिए टाइपस्क्रिप्ट के साथ)

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

आप प्रोटोटाइप को एनोटेट के साथ उल्टा कर सकते हैं

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

और फिर _fullname और _classname फ़ील्ड का उपयोग करें।

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

यहाँ एनोटेटिंग फंक्शन:

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

जैसा कि यह पहले से ही उत्तर दिया गया था, मैं सिर्फ जावास्क्रिप्ट में किसी ऑब्जेक्ट के निर्माता को प्राप्त करने के दृष्टिकोण में अंतर को इंगित करना चाहता था। कंस्ट्रक्टर और वास्तविक वस्तु / वर्ग नाम के बीच अंतर है। यदि निम्नलिखित आपके निर्णय की जटिलता को जोड़ता है तो शायद आप खोज रहे हैं instanceof। या शायद आपको खुद से पूछना चाहिए "मैं ऐसा क्यों कर रहा हूं? क्या यह वास्तव में मैं हल करने की कोशिश कर रहा हूं?"

टिप्पणियाँ:

obj.constructor.nameपुराने ब्राउज़र पर उपलब्ध नहीं है। मिलान (\w+)को ES6 शैली वर्गों को संतुष्ट करना चाहिए।

कोड:

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

परिणाम:

यहां छवि विवरण दर्ज करें

कोड: https://jsbin.com/wikiji/edit?js,console


3

मैं एक समान कठिनाई का सामना कर रहा था और यहां प्रस्तुत कोई भी समाधान मेरे लिए काम करने के लिए इष्टतम नहीं था। मेरे पास एक मोडल में सामग्री प्रदर्शित करने के लिए फ़ंक्शन की एक श्रृंखला थी और मैं कक्षा के कार्यों, विधियों को बनाते हुए एक एकल ऑब्जेक्ट परिभाषा के तहत इसे रीफ़ैक्टर करने की कोशिश कर रहा था। समस्या तब आई जब मैंने पाया कि एक विधि ने मोडल के अंदर कुछ नव-बटन बनाए हैं जो कि किसी एक कार्य के लिए ऑनक्लिक का उपयोग करते हैं - अब कक्षा का एक ऑब्जेक्ट। मैंने इन नौ बटन को संभालने के लिए अन्य तरीकों पर विचार (और अभी भी विचार कर रहा हूं) किया है, लेकिन मैं मूल विंडो में परिभाषित चर को स्वीप करके कक्षा के लिए चर नाम खोजने में सक्षम था। मैंने जो कुछ भी किया था, वह मेरी कक्षा के 'इंस्टाफॉफ़' से मेल खाने वाली चीज़ थी, और अगर एक से अधिक भी हो सकते हैं,

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

इसे इस्तेमाल करे:

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

1
क्या ऐसा कोई मामला है जिसमें यह obj.constructor.name से अधिक सटीक होगा? मैं अभी इस जटिलता का कोई कारण नहीं देखता हूं।
JHH

1

हम बस इसकी ज़रूरत है:

  1. एक फ़ंक्शन में एक निरंतर लपेटें (जहां फ़ंक्शन का नाम उस ऑब्जेक्ट के नाम के बराबर होता है जिसे हम प्राप्त करना चाहते हैं)
  2. ऑब्जेक्ट के अंदर तीर फ़ंक्शन का उपयोग करें

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.