JavaScriptのデータ型判定方法
2010/05/25
var string = new String('文字列'); //文字列のオブジェクト
var object = new Object(); //Objectオブジェクト
alert( string instanceof String ); //true これは期待通りの結果
alert( object instanceof Object ); //true これも期待通りの結果
alert( string instanceof Object ); //true どんなオブジェクトでもObjectオブジェクトのインスタンス扱いになってしまう
instanceof演算子の使用は自作のコンストラクタ(オブジェクト)の判定程度にとどめるのが無難でしょうか。
そして、最後のObject.toString()ですが、これはオブジェクトの判定に限れば一番有望な方法に見えます。下の例ではすべてのタイプのオブジェクトにメソッドを適用するためapply()メソッドを使っています。
var object = {}; //new Object()と同じ意味
var array = {}; //new Array()と同じ意味
var string = '文字列';
var stringObj = new String('文字列');
Object.prototype.toString.apply(object); //"[object Object]"
Object.prototype.toString.apply(array); //"[object Array]"
Object.prototype.toString.apply(string); //"[object String]"
Object.prototype.toString.apply(stringObj); //"[object String]"
この方法だと、生のオブジェクトの判定も可能で、さらに文字列/数値などもオブジェクト/非オブジェクトに関係なくデータ型を返すようになります。それでは、データ型別に有効な判定方法をまとめてみます(検証ブラウザFirefox3.5)。
undefined ⇒ typeof演算子
ヌル(null) ⇒ if ( aaa === null ) { …… }
配列 ⇒ instanceof演算子か、Object.toString()
関数 ⇒ typeof演算子かinstanceof演算子か、Object.toString()
正規表現 ⇒ instanceof演算子か、Object.toString()
自作クラス(コンストラクタ) ⇒ instanceof演算子
文字列/数値/bool値 ⇒ Object.toString()
ただ、jQuery(v1.4.1)の「Objectオブジェクト」判定メソッドであるjQuery.isPlainObject()は少し違う方法をとっているようです。
........
........
isPlainObject: function( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
return false;
}
// Not own constructor property must be Object
if ( obj.constructor
&& !hasOwnProperty.call(obj, "constructor")
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key;
for ( key in obj ) {}
return key === undefined || hasOwnProperty.call( obj, key );
},
........
........
jQuery.isPlainObject()を使って次の四つのObjectオブジェクト(obj1, obj2, pro, ins)を試してみました。
var obj1 = {}, //new Object()して作成したオブジェクト
obj2 = { hoge: 'HOGE' }, //プロパティを追加したオブジェクト
Con = function() { this.fuga = 'FUGA' },
pro = Con.prototype, //プロトタイプ(コンストラクタ評価時に自動的に作成されるオブジェクト)
ins = new Con(); //コンストラクタから作成された新規インスタンス
jQuery.isPlainObject(obj1) //true
jQuery.isPlainObject(obj2) //true
jQuery.isPlainObject(pro) //true
jQuery.isPlainObject(ins) //false
普通に作成されたObjectオブジェクトは当然のことながらtrueですが、インスタンス・オブジェクトがはじかれる一方、prototypeプロパティの場合trueを渡すようです。
