web-dev-qa-db-ja.com

Javascript変数の型を取得するためのより良い方法は?

typeofよりもJSの変数の型を取得するより良い方法はありますか?あなたがするときそれはうまく動作します:

> typeof 1
"number"
> typeof "hello"
"string"

しかし、試しても意味がありません。

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

私はinstanceofを知っていますが、そのためには事前に型を知っておく必要があります。

> [1,2] instanceof Array
true
> r instanceof RegExp
true

もっと良い方法はありますか?

237
Aillyn

Angus Crollは最近これについて興味深いブログ記事を書きました -

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

彼はさまざまなメソッドの長所と短所を調べ、新しいメソッド 'toType'を定義します -

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
206
ipr101

constructor.nameを使ってみることができます。

[].constructor.name
new RegExp().constructor.name

すべてのJavaScriptと同様に、誰かが結局これがどういうわけか悪であると指摘するので、 ここにこれをかなりうまくカバーしている答え へのリンクがあります。

別の方法はObject.prototype.toString.callを使うことです

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)
46
Alex Turpin

適度に優れた型キャプチャー関数は、 YUI3 によって使用されるものです。

var TYPES = {
    'undefined'        : 'undefined',
    'number'           : 'number',
    'boolean'          : 'boolean',
    'string'           : 'string',
    '[object Function]': 'function',
    '[object RegExp]'  : 'regexp',
    '[object Array]'   : 'array',
    '[object Date]'    : 'date',
    '[object Error]'   : 'error'
},
TOSTRING = Object.prototype.toString;

function type(o) {
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};

これはjavascriptによって提供されるプリミティブの多くを捉えますが、TYPESオブジェクトを修正することでいつでももっと追加することができます。 Safariのtypeof HTMLElementCollectionfunctionを報告しますが、type(HTMLElementCollection)はobjectを返します。

38
Nick Husher

次の機能が便利です。

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

またはES7で(さらなる改善があればコメント)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

結果:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

私に通知してくれてありがとう@johnrees:エラー、約束、generatorfunction

25
Vix

また、小さな例をipr101から変更することもできます。

Object.prototype.toType = function() {
  return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

そしてとして呼びなさい

"aaa".toType(); // 'string'
14
greymaster

一行関数:

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

これは jQuery.type() と同じ結果になります。

8
Yukulélé

Object.prototype.toStringを任意のオブジェクトに適用できます。

var toString = Object.prototype.toString;

console.log(toString.call([]));
//-> [object Array]

console.log(toString.call(/reg/g));
//-> [object RegExp]

console.log(toString.call({}));
//-> [object Object]

IEを除いて、これはすべてのブラウザでうまく機能します - 他のウィンドウから取得された変数でこれを呼び出すとき、それは単に[object Object]を吐き出します。

3
Andy E

私の2¢!本当に、ここで私がこれを投げている理由の一部は、答えの長いリストにもかかわらず、もう少し提供することですall in one解決策をタイプし、それをさらに含むように拡張する方法について、将来フィードバックをもらってくださいreal types

前述のように、次の解決策を使用して、ここで見つかったいくつかの解決策を組み合わせ、---fixを組み込んで の値)を返します。jQuery jQueryで定義されたオブジェクトがあれば。このメソッドをネイティブのObjectプロトタイプにも追加します。私は、それがタブーであることが多いことを知っています、それは他のそのような拡張を妨げることがあるので私はそれをuser bewareに任せます。この方法が気に入らない場合は、基本関数を好きな場所にコピーし、thisのすべての変数を渡す引数パラメーター(arguments [0]など)に置き換えてください。

;(function() {  //  Object.realType
    function realType(toLower) {
        var r = typeof this;
        try {
            if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery';
            else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
        }
        catch(e) { if (this['toString']) r = this.toString().slice(8, -1); }
        return !toLower ? r : r.toLowerCase();
    }
    Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType')
        ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType;
})();

それなら以下のように簡単に使えます。

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'

注:渡される引数は1つです。がtrueのブール値の場合、戻り値は常に小文字になります。

その他の例:

true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"

他のライブラリ(Moo、Proto、Yui、Dojoなど)でオブジェクトがいつ作成されたかを定義するなど、追加するものがある場合は、これをコメントまたは編集して追加してください。正確で正確です。 ORロールオーバーして GitHub 私はそれのために作りましたそして私に知らせてください。そこにはcdn minファイルへのクイックリンクもあります。

3
SpYk3HH
function getType(obj) {
    if(obj && obj.constructor && obj.constructor.name) {
        return obj.constructor.name;
    }
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

私の予備テストでは、これはかなりうまくいっています。最初のケースでは "new"で作成されたオブジェクトの名前が表示され、2番目のケースではそれ以外のすべてのものが検出されます。

私は(8, -1)を使っています。なぜなら、結果は常に[objectで始まり]で終わることを想定しているからです。しかし、すべてのシナリオに当てはまるとは限りません。

2
mpen