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
もっと良い方法はありますか?
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()
}
constructor.name
を使ってみることができます。
[].constructor.name
new RegExp().constructor.name
すべてのJavaScriptと同様に、誰かが結局これがどういうわけか悪であると指摘するので、 ここにこれをかなりうまくカバーしている答え へのリンクがあります。
別の方法はObject.prototype.toString.call
を使うことです
Object.prototype.toString.call([])
Object.prototype.toString.call(/./)
適度に優れた型キャプチャー関数は、 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 HTMLElementCollection
はfunction
を報告しますが、type(HTMLElementCollection)はobject
を返します。
次の機能が便利です。
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
また、小さな例をipr101から変更することもできます。
Object.prototype.toType = function() {
return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
そしてとして呼びなさい
"aaa".toType(); // 'string'
一行関数:
function type(obj) {
return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}
これは jQuery.type()
と同じ結果になります。
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]
を吐き出します。
私の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ファイルへのクイックリンクもあります。
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
で始まり]
で終わることを想定しているからです。しかし、すべてのシナリオに当てはまるとは限りません。