わりといい加減だった型判定について、確認の意味も込めてここに。
今後のためにも、頭の中を整理してみる。
型の判定に良く使用するもの
- ===
- typeof
- instanceof
- constructor
それぞれに利点があり、状況によって使い分けることになるが、処理速度は上記の順の通り、『===』が最も速い。
つまり、『===』<『typeof』<『instanceof』<『constructor』
下図はFirebugで計測した結果です。環境によって数値は変わると思われ、参考値としてご覧下さい。
100万回 for loopで回した処理に掛った時間
※『*constructor』は後に説明します。
一部、扱う型によって処理速度に差が見られた。
その二つの例外を以下に説明します。
存在しない変数を参照した場合の『undefined』について
var a; alert(typeof a);通常は上記のような場合、"undefined"が返ります。
変数に何も入ってなくとも、変数自体は存在する場合、処理に掛る時間は上図の通り、14ms程度だったのが、この変数"a"が存在しなかった場合はそれとは異なる結果が出た。
alert(typeof a);//aは存在しないこのような場合、エラーとはならず、処理に980msほど掛った。
『constructor』で型判定する場合について
上図に『*constructor』という値があります。これは『
foo.constructor == Number』などのように、以下の三つの型の変数のconstructorで型判定を行う場合の処理に掛る時間です。- Boolean
- String
- Number
その処理にかかる時間が上のグラフの『*constructor』の値となります。
さすがにこれほど差があると気になりますね。
しかし、Firebugでしか計測してませんので、あくまで参考までに。
上記のことを考慮しながら、型判定を行う関数を書いてみます。
Sample Code
function getType(o){
//処理速度 6:14:115:385
//『===』<『typeof』<『instanceof』<『constructor』
// typeof null => object
if (o === null)
return 'null';
//o === undefined => undefinedに代入可能なため×
//o == undefined => null == undefind はtrueなので×
if (typeof o == 'undefined')
return 'undefined';
if (typeof o == 'boolean')
return 'boolean';
if (typeof o == 'string')
return 'string';
if (typeof o == 'number')
return 'number';
// typeof array => object
if (o instanceof Array)
return 'array';
// typeof regexp => object
// regexp instanceof Object => true
if (o instanceof RegExp)
return 'regexp';
// typeof date => object
if (o instanceof Date)
return 'date';
if (typeof o == 'function')
return 'function';
if (typeof o == 'object')
return 'object'
return 'unknown';
}
この関数自体では処理速度を向上させることにはなりません。あくまで処理速度を考慮しながら個々の型に対する正確な判定を行っているにすぎないということです。
因みにjQueryのメソッドには型判定を行う『isFunction』や『isArray』がある。
この中身は、というと以下のようになっている。
var toString = Object.prototype.toString;
//...
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
},
isArray: function( obj ) {
return toString.call(obj) === "[object Array]";
},
調べてないが果たしてこれが最速(最適)なのか?undefinedについて
undefinedは何ともおかしな代物なので、私はundefinedをundefined足らしめる、ということをたまに行います。例えば、こんな感じで。
undefined = function(){return}();
var a;
alert(a === undefined);//true
とか(function( undefined ){
var a;
alert(a === undefined);//true
})();
みたいな感じで、確実にundefinedがundefinedであることを意識します。




