オブジェクトのタイプの名前を取得します


1193

そこにあるのJavaScriptの同等のJavaのではclass.getName()


この質問は、Javaのclass.getName()が何を行うかを知っていると想定しています。答えが私に役立つかどうかわからないので。
user34660

2
@ user34660私はそれがオブジェクトのタイプの名前を取得することであると安全に想定できると思います。
Stack Underflow

1
@StackUnderflow:例外ですが、実際にはありません。これは、オブジェクトの名前の取得クラスである、ないオブジェクトのと同じタイプを
イェルクWミッターク

1
@JörgWMittagああ、もちろん。安全に物事を想定しているとどうなりますか?
スタックアンダーフロー

回答:


1540

Javaに相当するJavaScriptはありclass.getName()ますか?

いいえ

ES2015の更新の名前はclass Foo {}ですFoo.name。のタイプにthing関係なく、のクラスの名前thingthing.constructor.nameです。ES2015環境の組み込みコンストラクタには正しいnameプロパティがあります。例えば(2).constructor.nameです"Number"


しかし、ここにさまざまなハックがあり、すべてが何らかの方法で失敗します。

ここにあなたが必要なことをするハックがあります-それがオブジェクトのプロトタイプを変更することに注意してください、それは人々が不平を言うものです(通常は正当な理由で)

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

これで、すべてのオブジェクトに関数がgetName()あり、コンストラクターの名前を文字列として返します。私はこれをFF3IE7でテストしましたが、他の実装について話すことはできません。

そうしたくない場合は、JavaScriptでタイプを判別するさまざまな方法について説明します...


私は最近、これをもう少し網羅的にするように更新しましたが、そうではありません。訂正は歓迎します...

constructorプロパティを使用しています...

すべてobjectにそのconstructorプロパティの値がありますが、それがどのようobjectに構築されたか、およびその値を使用して何をしたいかによって、それが役立つ場合と役に立たない場合があります。

一般的に言えば、次のようにconstructorプロパティを使用してオブジェクトのタイプをテストできます。

var myArray = [1,2,3];
(myArray.constructor == Array); // true

したがって、ほとんどのニーズに十分対応できます。それは言った...

注意事項

動作しませんAT ALLを、多くの場合、

このパターンは壊れていますが、非常に一般的です。

function Thingy() {
}
Thingy.prototype = {
    method1: function() {
    },
    method2: function() {
    }
};

Objectsを介しnew Thingyて構築されたは、ではなくconstructorを指すプロパティを持ちます。ですから、私たちは最初からうまくいきます。自分が制御していないコードベースを信頼することはできません。ObjectThingyconstructor

多重継承

それほど明白ではない例は、多重継承の使用です。

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

期待どおりに機能しなくなります。

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

そのためobject、テストにと異なるobjectセットがある場合、予期しない結果が生じる可能性がありますprototype。この議論の範囲外でこれを回避する方法があります。

constructorプロパティには他にも用途があり、興味深いものもあれば、それほど多くないものもあります。今のところ、この議論には関係がないため、これらの使用法については詳しく説明しません。

クロスフレームおよびクロスウィンドウでは機能しません

.constructorタイプチェックにを使用すると、異なるwindowオブジェクトからのオブジェクトのタイプ(iframeまたはポップアップウィンドウなど)をチェックするときに機能しなくなります。これはconstructor、各「ウィンドウ」に各コアタイプの異なるバージョンがあるためです。

iframe.contentWindow.Array === Array // false

instanceof演算子を使用しています...

instanceofオペレータは、テストのきれいな方法であるobjectと同じように、同様のタイプを、それ自身の潜在的な問題を持っているconstructorプロパティ。

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

しかしinstanceof、リテラル値では機能しません(リテラルはそうではないためObjects

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

リテラルを機能Objectさせるには、次のようにラップする必要があります。instanceof

new Number(3) instanceof Number // true

.constructorので、チェックはリテラルの罰金を作品.メソッド呼び出しが暗黙のうちに、それぞれのオブジェクト型にリテラルをラップ

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

なぜ3に2つのドットがあるのですか?JavaScriptは最初のドットを小数点として解釈するため;)

クロスフレームおよびクロスウィンドウでは機能しません

instanceofconstructorプロパティチェックと同じ理由で、異なるウィンドウ間でも機能しません。


nameプロパティのプロパティを使用していconstructorます...

動作しませんAT ALLを、多くの場合、

再度、上記を参照してください。以下のためにそれはかなり一般的ですconstructor全く、完全に間違っていると役に立たないこと。

<IE9では機能しません

を使用myObjectInstance.constructor.nameすると、constructor使用される関数の名前を含む文字列が得られますが、constructor前述のプロパティに関する注意事項の影響を受けます。

IE9以降の場合、サポートにサルパッチを適用できます。

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

問題の記事の更新バージョン。これは記事が公開されてから3か月後に追加されました。これは、記事の作者であるMatthew Scharleyが使用する推奨バージョンです。この変更は、前のコードの潜在的な落とし穴指摘するコメントに触発されました。

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
}

Object.prototype.toStringの使用

それはよう、判明この記事の詳細を使用でき、Object.prototype.toString低レベルとの一般的な実装を- toString-のためのタイプを取得するために、すべての組み込み型

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

次のような短いヘルパー関数を書くことができます

function type(obj){
    return Object.prototype.toString.call(obj).slice(8, -1);
}

残骸を取り除き、タイプ名だけを取得する

type('abc') // String

ただし、Objectすべてのユーザー定義型に対して返されます。


すべての注意事項...

これらはすべて1つの潜在的な問題の影響を受けます。それが、問題のオブジェクトがどのように構築されたかという問題です。オブジェクトを構築するさまざまな方法と、タイプチェックのさまざまなメソッドが返す値を次に示します。

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

この一連の例にはすべての順列が含まれているわけではありませんが、必要に応じて厄介なことがどのように発生するかについてのアイデアを提供するのに十分であることを望みます。何も想定しないでください。自分が何をしているのか正確に理解していない場合、微妙な問題が発生しないため、予期しないコード破損が発生する可能性があります。

注意:

typeof演算子の議論は明白な省略のように見えるかもしれませんがobject、それは非常に単純化されているので、それが与えられた型であるかどうかを識別するのを助けるのに本当に役に立ちません。どこtypeofが役に立つかを理解することは重要ですが、私は現在、この議論にそれほど関連があるとは感じていません。私の心は変わりますが。:)


58
まあ、私もそうかもしれないと思った-スタックオーバーフローのポイントはwikiのようになることであり、これはその意図とはるかに一致していると思います。とにかく、もう少し徹底的になりたかっただけです。
Jason Bunting

以下の回答を繰り返します--- Objectプロトタイプへの拡張がIE8で機能しません-IE8で何が機能するか知っていますか?
アダム

5
この関数a(){this.a = 1;}関数b(){this.b = 2;のように実行すると機能します。} b.prototype = new a(); // bはb.prototype.constructor = b;から継承します //プロトタイプ継承の正しい方法var f = new b(); // bコンストラクターで新しいオブジェクトを作成します(f.constructor == b); // TRUE(f.constructor == a); // FALSE
ボリスハマノフ2011年

9
さて、これがStackOverflowでの答えのほとんどがどうあるべきかです。(回答の長さを定義パラメータとして取らないでください。ただし、包括性を
考慮してください

44
オブジェクトのconstructorメソッドを(.toString()またはのどちらかで.name)検査する手法は、JavascriptがuglifyなどのツールまたはRailsアセットパイプラインで縮小化されている場合、機能しないことに注意することが重要です。ミニファイはコンストラクターの名前を変更するので、のような誤ったクラス名になりnます。このシナリオの場合は、オブジェクトのプロパティを手動で定義し、className代わりにそれを使用することをお勧めします。
Gabe Martin-Dempesy

126

ジェイソン・バンティングの答えは、私が必要なものを見つけるのに十分な手がかりを与えてくれました:

<<Object instance>>.constructor.name

したがって、たとえば、次のコードでは、

function MyObject() {}
var myInstance = new MyObject();

myInstance.constructor.name戻り"MyObject"ます。


22
完全を期すために、変数に割り当てられた無名関数ではなく、名前付き関数をコンストラクターとして使用した場合にのみ、constructor.nameの使用が機能することに言及する価値があるかもしれません。
Matthew Crumley、

20
完全を期すために、IEブラウザーでは機能しないことを言及する価値があるかもしれません---それらは関数の "name"属性をサポートしていません。
Eugene Lazutkin

2
@Eugene-私はそれを忘れていました...私はブラウザの外でJavaScriptを実行するのにあまりにも多くの時間を費やしたと思います。
Matthew Crumley、

2
function getType(o) { return o && o.constructor && o.constructor.name }
justin.m.chase 2017

これはとても包括的なものです。
ibic

26

私が使用する小さなトリック:

function Square(){
    this.className = "Square";
    this.corners = 4;
}

var MySquare = new Square();
console.log(MySquare.className); // "Square"

11
私は特にこれが好きではありません。それは一種の汚いトリックです。一方、コンストラクターが多すぎない場合は、問題なく動作する可能性があります。
pimvdb 2011年

13
@pimvdb:オブジェクトのプロトタイプを変更するよりもクリーンだと思います。
Daniel Szabo 2013年

4
@DanielSzaboプロパティがプロトタイプのすべてのインスタンス間で同じ値を持つ必要がある場合、私は間違いなくプロトタイプにそれを置くことを好む-各インスタンスにそれを置くことは超冗長であり、メタデータがプロトタイプ自体から欠落している。そうは言っても、ES6では最も賢明なソリューションが採用されました。もしあればclass Square、名前はSquare.name/ MySquare.constructor.nameではなく/ Square.prototype.nameです。置くことによってname、コンストラクタ関数にはプロトタイプまたは任意のインスタンスを汚染しませんが、どちらかからアクセス可能です。
アンディ

17

更新

正確には、OPは特定のオブジェクトのコンストラクター名を取得する関数を要求したと思います。JavaScriptに関しては、objectはタイプを持たず、のタイプであり、それ自体です。ただし、オブジェクトごとにコンストラクターが異なる場合があります。

Object.prototype.getConstructorName = function () {
   var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
   var cname = str.match(/function\s(\w*)/)[1];
   var aliases = ["", "anonymous", "Anonymous"];
   return aliases.indexOf(cname) > -1 ? "Function" : cname;
}

new Array().getConstructorName();  // returns "Array"
(function () {})().getConstructorName(); // returns "Function"

 


注:以下の例は非推奨です。

Christian Sciberrasによってリンクされたブログ投稿には、その方法の良い例が含まれています。つまり、Objectプロトタイプを拡張することにより、

if (!Object.prototype.getClassName) {
    Object.prototype.getClassName = function () {
        return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
    }
}

var test = [1,2,3,4,5];

alert(test.getClassName()); // returns Array

2
いいですね、でも名前を付け直します。JSにはクラスがありません。
mikemaccana

@nailer-更新された関数を使用することをお勧めします。古い関数は単に歴史的な理由で保持されています。
Saul

これは機能しますが、オブジェクトを最初の引数として受け取り、これを関数内で「this」の代わりに使用する関数を作成することにより、Object.prototypeを変更せずに実行できることに注意してください。
Matt Browne

2
@マット-はい。:これは、オブジェクトのメソッドを持つことが、より簡潔であることだけであるtest.getClassName()getClassName.apply(test)
ソール

12

Object.prototype.toStringの使用

この投稿の詳細として、Object.prototype.toString(toStringの低レベルで汎用的な実装)を使用して、すべての組み込み型の型を取得できることがわかりました

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

次のような短いヘルパー関数を書くことができます

function type(obj){
    return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}

return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function

6
オブジェクト名を解析するために正規表現を使用する必要はありません。ただ使用してください.slice()Object.prototype.toString.call(obj).slice( 8, -1 );
bobobobo

9

ここでは、instanceofの欠点を解決するために私が考え出したソリューションを示します。クロスウィンドウやクロスフレームからオブジェクトのタイプをチェックでき、プリミティブタイプには問題がありません。

function getType(o) {
    return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
    var ret = false,
    isTypeAString = getType(type) == "String",
    functionConstructor, i, l, typeArray, context;
    if (!isTypeAString && getType(type) != "Function") {
        throw new TypeError("type argument must be a string or function");
    }
    if (obj !== undefined && obj !== null && obj.constructor) {
        //get the Function constructor
        functionConstructor = obj.constructor;
        while (functionConstructor != functionConstructor.constructor) {
            functionConstructor = functionConstructor.constructor;
        }
        //get the object's window
        context = functionConstructor == Function ? self : functionConstructor("return window")();
        //get the constructor for the type
        if (isTypeAString) {
            //type is a string so we'll build the context (window.Array or window.some.Type)
            for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
                context = context[typeArray[i]];
            }
        } else {
            //type is a function so execute the function passing in the object's window
            //the return should be a constructor
            context = type(context);
        }
        //check if the object is an instance of the constructor
        if (context) {
            ret = obj instanceof context;
            if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
                ret = obj.constructor == context
            }
        }
    }
    return ret;
}

isInstanceには、オブジェクトとタイプの2つのパラメーターが必要です。それがどのように機能するかの本当のトリックは、オブジェクトが同じウィンドウからのものであるかどうかをチェックし、そうでない場合はオブジェクトのウィンドウを取得することです。

例:

isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true

function Animal() {}
function Dog() {}
Dog.prototype = new Animal();

isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false

type引数は、コンストラクターを返すコールバック関数にすることもできます。コールバック関数は、提供されたオブジェクトのウィンドウである1つのパラメーターを受け取ります。

例:

//"Arguments" type check
var args = (function() {
    return arguments;
}());

isInstance(args, function(w) {
    return w.Function("return arguments.constructor")();
}); //true

//"NodeList" type check
var nl = document.getElementsByTagName("*");

isInstance(nl, function(w) {
    return w.document.getElementsByTagName("bs").constructor;
}); //true

注意すべき点の1つは、IE <9ではすべてのオブジェクトにコンストラクターが提供されないため、上記のNodeListのテストでfalseが返され、isInstance(alert、 "Function")でもfalseが返されることです。


8

私は実際に同様のものを探していて、この質問に出くわしました。これがタイプを取得する方法です:jsfiddle

var TypeOf = function ( thing ) {

    var typeOfThing = typeof thing;

    if ( 'object' === typeOfThing ) {

        typeOfThing = Object.prototype.toString.call( thing );

        if ( '[object Object]' === typeOfThing ) {

            if ( thing.constructor.name ) {
                return thing.constructor.name;
            } 

            else if ( '[' === thing.constructor.toString().charAt(0) ) {
                typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
            } 

            else {

                typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );

                if ( typeOfThing ) { 
                    return typeOfThing[1];
                } 

                else {
                    return 'Function';
                }
            }
        } 

        else {
            typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
        }
    }

    return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}

7

あなたは次のsomevar.constructor.nameように使うべきです:

    
    const getVariableType = a => a.constructor.name.toLowerCase();

    const d = new Date();
    const res1 = getVariableType(d); // 'date'
    const num = 5;
    const res2 = getVariableType(num); // 'number'
    const fn = () => {};
    const res3 = getVariableType(fn); // 'function'

    console.log(res1); // 'date'
    console.log(res2); // 'number'
    console.log(res3); // 'function'


6

constructor.name可能な場合は使用し、できない場合は正規表現関数を使用します。

Function.prototype.getName = function(){
  if (typeof this.name != 'undefined')
    return this.name;
  else
    return /function (.+)\(/.exec(this.toString())[1];
};

6

Agave.JSkind()関数は以下を返します:

  • 継承ツリーで最も近いプロトタイプ
  • 「null」や「undefined」などのプリミティブ型の場合、プリミティブ名。

それがどのように作成されたかに関係なく、すべてのJSオブジェクトとプリミティブで機能し、驚きはありません。例:

数字

kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'

NaN

kind(NaN) === 'NaN'

文字列

kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'

ブール

kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'

配列

kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'

オブジェクト

kind({a:1}) === 'Object'
kind(new Object()) === 'Object'

日付

kind(new Date()) === 'Date'

機能

kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'

未定義

kind(undefined) === 'undefined'

ヌル

kind(null) === 'null'

5

instanceof演算子を使用して、オブジェクトが別のインスタンスであるかどうかを確認できますが、クラスがないため、クラス名を取得できません。


それはJavaScriptが言語構造などのクラスを持っていないのは事実だが、一般的な慣習は、オブジェクトの型がクラスと呼ばれていることをまだ..です
ソール

2
@greg確かにinstanceof、オブジェクトが別のオブジェクトから継承するかどうかを確認するだけです。たとえば、単純な[]配列は配列から継承しますが、配列はオブジェクトからも継承します。ほとんどのオブジェクトには複数のレベルの継承があるため、最も近いプロトタイプを見つけることはより良いテクニックです。方法については私の回答を参照してください。
mikemaccana

4

受け入れられた回答に基づく実装は次のとおりです。

/**
 * Returns the name of an object's type.
 *
 * If the input is undefined, returns "Undefined".
 * If the input is null, returns "Null".
 * If the input is a boolean, returns "Boolean".
 * If the input is a number, returns "Number".
 * If the input is a string, returns "String".
 * If the input is a named function or a class constructor, returns "Function".
 * If the input is an anonymous function, returns "AnonymousFunction".
 * If the input is an arrow function, returns "ArrowFunction".
 * If the input is a class instance, returns "Object".
 *
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @see <a href="https://stackoverflow.com/a/332429/14731">https://stackoverflow.com/a/332429/14731</a>
 * @see getFunctionName
 * @see getObjectClass 
 */
function getTypeName(object)
{
  const objectToString = Object.prototype.toString.call(object).slice(8, -1);
  if (objectToString === "Function")
  {
    const instanceToString = object.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "ArrowFunction";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
      return "AnonymousFunction";
    return "Function";
  }
  // Built-in types (e.g. String) or class instances
  return objectToString;
};

/**
 * Returns the name of a function.
 *
 * If the input is an anonymous function, returns "".
 * If the input is an arrow function, returns "=>".
 *
 * @param {Function} fn a function
 * @return {String} the name of the function
 * @throws {TypeError} if {@code fn} is not a function
 * @see getTypeName
 */
function getFunctionName(fn)
{
  try
  {
    const instanceToString = fn.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "=>";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
    {
      const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
      if (objectToString === "Function")
        return "";
      throw TypeError("object must be a Function.\n" +
        "Actual: " + getTypeName(fn));
    }
    return match[1];
  }
  catch (e)
  {
    throw TypeError("object must be a Function.\n" +
      "Actual: " + getTypeName(fn));
  }
};

/**
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @throws {TypeError} if {@code object} is not an Object
 * @see getTypeName
 */
function getObjectClass(object)
{
  const getFunctionName = /^function ([^(]+)\(/;
  const result = object.constructor.toString().match(getFunctionName)[1];
  if (result === "Function")
  {
    throw TypeError("object must be an Object.\n" +
      "Actual: " + getTypeName(object));
  }
  return result;
};


function UserFunction()
{
}

function UserClass()
{
}

let anonymousFunction = function()
{
};

let arrowFunction = i => i + 1;

console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(\"text\"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));

他に選択肢がない場合にのみ、コンストラクタプロパティを使用します。


3

「instanceof」演算子を使用して、オブジェクトが特定のクラスのインスタンスであるかどうかを判断できます。オブジェクトのタイプの名前がわからない場合は、そのコンストラクタープロパティを使用できます。オブジェクトのコンストラクタプロパティは、オブジェクトの初期化に使用される関数への参照です。例:

function Circle (x,y,radius) {
    this._x = x;
    this._y = y;
    this._radius = raduius;
}
var c1 = new Circle(10,20,5);

ここで、c1.constructorはCircle()関数への参照です。typeof演算子を使用することもできますが、typeof演算子には限られた情報しか表示されません。1つの解決策はtoString()、Objectグローバルオブジェクトのメソッドを使用することです。たとえば、オブジェクト(myObjectなど)がある場合toString()、グローバルオブジェクトのメソッドを使用して、myObjectのクラスのタイプを判別できます。これを使って:

Object.prototype.toString.apply(myObject);

3

あなたが持っていると言う var obj;

「オブジェクト」、「配列」、「文字列」など、objの型の名前だけが必要な場合は、次のように使用できます。

Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');

2

取得できる最も近いのはですがtypeof、あらゆる種類のカスタムタイプに対して「オブジェクト」のみを返します。それらについては、Jason Buntingを参照してください。

編集、ジェイソンは何らかの理由で投稿を削除したので、オブジェクトのconstructorプロパティを使用します。


ええ、すみません-instanceof()がより良い方法だと思ったので削除しましたが、参照として使用できるように、削除を取り消しただけです。
Jason Bunting

2
同様の問題があるため、他の人が後で質問に回答する場合に限り、完全ではない回答も役に立ちます。したがって、実際にそれらを削除してはなりません。間違った回答の削除を保存します。
だらしない2008

2
ええ、私は知っています-あなたは合唱団に説教している、私は他の人にまったく同じことを言った。私たちが真実であるとわかっているものを生きることは、見た目よりも難しいことがよくあります。:)
Jason Bunting

0

誰かがjQueryで動作するソリューションを探していた場合、これが調整されたwikiコードです(元のコードはjQueryを壊します)。

Object.defineProperty(Object.prototype, "getClassName", {
    value: function() {
        var funcNameRegex = /function (.{1,})\(/;
        var results = (funcNameRegex).exec((this).constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    }
});

ええ、jQueryは「hasOwnProperty」チェックを実行できないため、を列挙しgetNameてフォールオーバーします。
nicodemus13

0

Lodashには多くのisMethodがあるので、Lodashを使用している場合は、次のようなミックスインが便利です。

  // Mixin for identifying a Javascript Object

  _.mixin({
      'identify' : function(object) {
        var output;
          var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments', 
              'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber', 
              'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']

          this.each(isMethods, function (method) {
              if (this[method](object)) {
                output = method;
                return false;
              }
          }.bind(this));
      return output;
      }
  });

次のように機能する「identify」と呼ばれるlodashへのメソッドを追加します。

console.log(_.identify('hello friend'));       // isString

プランカー:http ://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN


0

わかりました、私はここ数年、ゆっくりとキャッチオールメソッドを構築してきましたlol!秘訣は:

  1. クラスを作成するためのメカニズムがあります。
  2. ユーザーが作成したすべてのクラス、プリミティブ、およびネイティブコンストラクターによって作成/生成された値をチェックするメカニズムがあります。
  3. 上記の機能がコード/アプリケーション/ライブラリ/などに浸透するように、ユーザーが作成したクラスを新しいクラスに拡張するメカニズムがあります。

例として(または問題への対処方法を確認するには)、githubで次のコードを確認してください

classOf =classOfIs =、及び又は defineSubClass =(バッククォート無し( `))。

ご覧のようにclassOf、プリミティブ、ユーザー定義クラス、ネイティブコンストラクターを使用して作成された値、Null、NaNなどに関係なく、常にクラス/コンストラクタータイプ名を強制的に与えるメカニズムがいくつかあります。すべての1つのjavascript値について、classOf関数から一意の型名を取得します。さらに、実際のコンストラクターにsjl.classOfIs渡して、値の型をチェックできるほか、型名も渡すことができます。だから例えば:

`` `//長い名前空間は許してください!しばらく使用するまでは影響がわかりませんでした(笑)

var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
    constructor: function SomeCustomClass () {},
    // ...
}),

HelloIterator = sjl.ns.stdlib.Iterator.extend( 
    function HelloIterator () {}, 
    { /* ... methods here ... */ },
    { /* ... static props/methods here ... */ }
),

helloIt = new HelloIterator();

sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`

var someString = 'helloworld';

sjl.classOfIs(someString, String) === true; // `true`

sjl.classOfIs(99, Number) === true; // true

sjl.classOf(NaN) === 'NaN'; // true

sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`

// etc..

// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!

「」

上記の設定の使用方法の詳細に興味がある場合は、リポジトリを参照してくださいhttps : //github.com/elycruz/sjljs

また、主題に関する内容の本:-Stoyan Stefanovによる「JavaScriptパターン」。-「Javascript-決定的なガイド」デビッドフラナガンによって。-および他の多くの..(search le` web)。

また、あなたはすぐに私はおよそここで話している機能をテストすることができます- http://sjljs.elycruz.com/0.5.18/tests/for-browser/(もURL内0.5.18パスはgithubのからソースを持っていますそこにnode_modulesなどを差し引いたもの)。

ハッピーコーディング!


0

かなりシンプル!

  • JSで何かのタイプを取得するための私のお気に入りの方法
function getType(entity){
    var x = Object.prototype.toString.call(entity)
    return x.split(" ")[1].split(']')[0].toLowerCase()
}
  • JSで何かのタイプをチェックする私のお気に入りの方法
function checkType(entity, type){
    return getType(entity) === type
}

-1

を使用しclass.nameます。これはでも機能しfunction.nameます。

class TestA {}
console.log(TestA.name); // "TestA"

function TestB() {}
console.log(TestB.name); // "TestB"

質問classはインスタンスではなく明確に述べています。
qwertzguy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.