web-dev-qa-db-ja.com

JavaScriptオブジェクトのクラスを取得する方法

JavaScriptオブジェクトを作成しましたが、そのオブジェクトのクラスをどのように判断することができますか?

Javaの.getClass()メソッドに似たものが欲しいのですが。

593
DNB5brims

JavaScriptにはJavaの getClass() とまったく同じものはありません。これは主に、JavaScriptが プロトタイプベースの言語 であるのに対して、Javaが クラスベース のものであるのとは対照的です。

あなたがgetClass()に何を必要としているかに応じて、JavaScriptにはいくつかのオプションがあります。

いくつかの例:

function Foo() {}
var foo = new Foo();

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42

注:Uglifyを使ってコードをコンパイルしている場合は、非グローバルクラス名が変更されます。これを防ぐために、Uglifyには --mangle paramがあり、falseに設定すると gulp または grunt になります。

833
earl
obj.constructor.name

現代のブラウザでは信頼できる方法です。 ES6ではFunction.nameが正式に標準に追加され、これがJavaScriptオブジェクトの「クラス」を文字列として取得する標準準拠の手段になりました。オブジェクトがvar obj = new MyClass()でインスタンス化されている場合、 "MyClass"を返します。

数値の場合は "Number"、配列の場合は "Array"、関数の場合は "Function"などが返されます。通常は予想どおりに動作します。失敗する唯一のケースは、Object.create( null )によってプロトタイプなしでオブジェクトが作成された場合、またはオブジェクトが匿名で定義された(名前のない)関数からインスタンス化された場合です。

コードを縮小している場合は、ハードコードされた文字列と比較するのは安全ではありません。たとえば、obj.constructor.name == "MyType"を確認する代わりに、obj.constructor.name == MyType.nameを確認します。あるいは単にコンストラクター同士を比較するだけですが、各DOMにはコンストラクター関数の異なるインスタンスがあるため、DOMの境界を越えては機能しません。したがって、それらのコンストラクターでオブジェクト比較を行うことは機能しません。

プロトタイプを連鎖するときの注意

奇妙なことに、constructor.nameはプロトタイプチェーンで使用される最も基本的な関数の名前を返します。残念ながら直感的にはわかりません。たとえば、BAからプロトタイプ的に派生し、Bbの新しいインスタンスを作成した場合、b.constructor.nameは "A"を返しますが、これは間違っているようです。ただし、単一レベルのプロトタイプおよびすべてのプリミティブに対してはうまく機能します。

244
devios1

この関数は、Object.prototype.toString.call(someObject)から"undefined""null"、または"class"内の[object class]のいずれかを返します。

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "null";
// etc...
27
Eli Grey

「疑似クラス」を取得するには、次のようにしてコンストラクタ関数を取得します。

obj.constructor

継承を行うときにconstructorが正しく設定されていると仮定します。これは次のようなものです。

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

これら2行は、

var woofie = new Dog()

woofie.constructorDogを指すようにします。 Dogはコンストラクタ関数であり、Functionオブジェクトです。しかし、あなたはif (woofie.constructor === Dog) { ... }をすることができます。

あなたが文字列としてクラス名を取得したい場合は、私は以下がうまくいっているのがわかりました:

http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}

それはコンストラクタ関数に到達し、それを文字列に変換し、そしてコンストラクタ関数の名前を抽出します。

obj.constructor.nameはうまく機能したかもしれませんが、標準ではありません。これはChromeとFirefoxにありますが、IE 9またはIE 10 RTMを含むIEにはありません。

17

コンストラクタプロパティ を使用して、オブジェクトを作成したコンストラクタ関数への参照を取得できます。

function MyObject(){
}

var obj = new MyObject();
obj.constructor; // MyObject

実行時にオブジェクトの種類を確認する必要がある場合は、 instanceof 演算子を使用できます。

obj instanceof MyObject // true
10
CMS

下位互換性の切れ目のない記録であるECMAScript 6を維持するため、JavaScriptにはclassタイプがありません(誰もがこれを理解しているわけではありません)。 doesプロトタイプを作成するためのclass構文の一部としてclassキーワードがありますが、まだクラスと呼ばれるものはありませんです。 JavaScriptは現在ではなく、従来のOOP言語ではなかったになっています。クラスの観点からJSを話すことは、誤解を招くか、プロトタイプの継承をまだ理解していないことを示すだけです(実際にそのままにしておきます)。

つまり、this.constructorは、依然としてconstructor関数への参照を取得する優れた方法です。 this.constructor.prototypeは、プロトタイプ自体にアクセスする方法です。これはJavaではないため、クラスではありません。インスタンスがインスタンス化されたプロトタイプオブジェクトです。 ES6構文糖を使用してプロトタイプチェーンを作成する例を次に示します。

class Foo {
  get foo () {
    console.info(this.constructor, this.constructor.name)
    return 'foo'
  }
}

class Bar extends Foo {
  get foo () {
    console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
    console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))

    return `${super.foo} + bar`
  }
}

const bar = new Bar()
console.dir(bar.foo)

これは、babel-nodeを使用して出力するものです。

> $ babel-node ./foo.js                                                                                                                   ⬡ 6.2.0 [±master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'

そこにある! 2016年には、JavaScriptにclassキーワードがありますが、クラスタイプはありません。 this.constructorはコンストラクター関数を取得する最良の方法であり、this.constructor.prototypeはプロトタイプ自体へのアクセスを取得する最良の方法です。

5
james_womack

私は今一般的に動作する状況があり、これを使用しました:

class Test {
  // your class definition
}

nameByType = function(type){
  return type.prototype["constructor"]["name"];
};

console.log(nameByType(Test));

それはあなたがオブジェクトのインスタンスを持っていない場合、私はタイプ入力によってクラス名を取得することがわかった唯一の方法です。

(ES2017で書かれています)

ドット表記もうまく機能します

console.log(Test.prototype.constructor.name); // returns "Test" 
4
mtizziani

object.constructor.toString()がchomeで返されるのではなく、IEでfunction objectClass () {} return [object objectClass]が見つかりました。だから、私は http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects-のコードを考える 私はコードを修正した次のように:

コード:

var getObjectClass = function (obj) {
        if (obj && obj.constructor && obj.constructor.toString()) {

                /*
                 *  for browsers which have name property in the constructor
                 *  of the object,such as chrome 
                 */
                if(obj.constructor.name) {
                    return obj.constructor.name;
                }
                var str = obj.constructor.toString();
                /*
                 * executed if the return of object.constructor.toString() is 
                 * "[object objectClass]"
                 */

                if(str.charAt(0) == '[')
                {
                        var arr = str.match(/\[\w+\s*(\w+)\]/);
                } else {
                        /*
                         * executed if the return of object.constructor.toString() is 
                         * "function objectClass () {}"
                         * for IE Firefox
                         */
                        var arr = str.match(/function\s*(\w+)/);
                }
                if (arr && arr.length == 2) {
                            return arr[1];
                        }
          }
          return undefined; 
    };
3
zzy7186

ES6のJavascriptクラスの場合は、object.constructorを使用できます。以下のクラス例では、getClass()メソッドは期待どおりにES6クラスを返します。

var Cat = class {

    meow() {

        console.log("meow!");

    }

    getClass() {

        return this.constructor;

    }

}

var fluffy = new Cat();

...

var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();

ruffles.meow();    // "meow!"

getClassメソッドからクラスをインスタンス化する場合は、かっこで囲むようにしてください。 ruffles = new ( fluffy.getClass() )( args... );

3
Hugheth

JavaScriptでは、クラスはありませんが、コンストラクタ名がほしいと思い、obj.constructor.toString()が必要なものを教えてくれます。

2
Jikhan

Dfaに同意してください。名前付きクラスが見つからないときにプロトタイプをクラスと見なすのはそのためです。

これはEli Greyが投稿したものの私の考え方に合うようにアップグレードされた機能です。

function what(obj){
    if(typeof(obj)==="undefined")return "undefined";
    if(obj===null)return "Null";
    var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
    if(res==="Object"){
        res = obj.constructor.name;
        if(typeof(res)!='string' || res.length==0){
            if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
            if(obj instanceof Array)return "Array";// Array prototype is very sneaky
            return "Object";
        }
    }
    return res;
}
1
Antkhan

私のライブラリを試してみてください TypeScript-class-helpers

import { CLASS } from 'TypeScript-class-helpers'

@CLASS.NAME('Example')
class Example {

}

console.log(CLASS.getName(Example) === 'Example') // true
console.log(CLASS.getNameFromObject(new Example()) === 'Example') // true
console.log(CLASS.getBy('Example') === Example) // true

こうすると、uglifyプロセスの後でもクラス名を使うことができます。

インストール:

npm i TypeScript-class-helpers
0

Javascriptはクラスのない言語です。Javaのようにクラスの振る舞いを静的に定義するクラスはありません。 JavaScriptは、メソッドや継承など、オブジェクトのプロパティを定義するためにクラスではなくプロトタイプを使用します。 JavaScriptのプロトタイプを使用して、多くのクラスベースの機能をシミュレートすることが可能です。

0
dfa