オブジェクトまたはクラスの名前を取得する


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。それらの1つを取得することは可能ですか?


:あなたはこの見たいかもしれませんstackoverflow.com/questions/789675/...
のSudhir Bastakoti

回答:


349

オブジェクトのコンストラクター関数を取得し、そのnameプロパティを調べます。

myObj.constructor.name

「myClass」を返します。


175
注意してください!JavaScriptを縮小する場合、コンストラクターの名前が変更されます。
dB。

34
便利ですが、別の注意点があります。オブジェクトに(を除いて)プロトタイプチェーンがある場合、オブジェクトの作成に使用されたコンストラクターの名前ではなく、そのチェーンの最初のリンクのObject名前を取得します。次の例を見てください。その後、予想外に返し、ありません。function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;me.constructor.name'Daddy''Me'
mklement0 2013

7
また、nameプロパティは<IE9
Jason

10
そして、変数を通して宣言されたオブジェクトで使用された場合、これは空の文字列を返します:var Foo = function() {};
Aleksandr Makov

3
Chromeコンソールはあなたが知らないことを知っています: > myclass=(function(){}); new myclassプリントmyclass {}
Hugh Allen

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を使用する場合(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 = {}));

プロトタイプに前もって注釈を付けることができます

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

これはすでに回答されているので、JavaScriptでオブジェクトのコンストラクターを取得する方法の違いを指摘したかっただけです。コンストラクターと実際のオブジェクト/クラス名には違いがあります。以下があなたの決定の複雑さを増すなら、多分あなたは探してい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

私も同様の困難に直面しており、ここで紹介する解決策はどれも、自分が取り組んでいることに最適ではありませんでした。私が持っていたのは、モーダルでコンテンツを表示する一連の関数であり、クラスの関数、メソッドを作成する単一のオブジェクト定義の下でそれをリファクタリングしようとしていました。問題の1つは、メソッドの1つが関数の1つ(現在はクラスのオブジェクト)へのonClickを使用するいくつかのナビゲーションボタンをモーダル内に作成したことを発見したときです。これらのナビゲーションボタンを処理する他のメソッドを検討しました(現在も検討しています)が、親ウィンドウで定義された変数をスイープすることにより、クラス自体の変数名を見つけることができました。私がしたことは、クラスの「インスタンス」に一致するものを検索することでした。複数ある場合は、

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.