2011年12月06日 14:30 [Edit]
javascript - typeof()を再発明する
まてよ、ということは…
underscore.js の _.isRegExp について - ”><xmp>TokuLog 改メ tokuhirom’s blogmultiple frames のときにハマるということらしい。Perfection kills ≫ `instanceof` considered harmful (or how to write a robust `isArray`)
This means that creating isArray function could not be simpler than:
これを応用すればまっとうなtypeofを作れるってこと?
JavaScriptのtypeofは役立たず
よく知られているように、JavaScriptのtypeofは使えない子です。JavaScript: The Good Partsでも「ひどいパーツ」と名指しです。
p(typeof(undefined));
p(typeof(null));
p(typeof(false));
p(typeof(0));
p(typeof(''));
p(typeof([]));
p(typeof({}));
p(typeof(function(){}));
p(typeof(new Date));
p(typeof(/[\S\s]/g));
p(typeof(document));
p(typeof(document.createElement('div')));
function YourOwnObject(a){
this.a = a;
};
var foo = new YourOwnObject;
p(typeof(foo));
typeof(null)がobjectだったり、ArrayとObjectの区別がつかなかったり。わけがわからないよ。
Object.prototype.toString.call()があるじゃない
ところがObject.prototype.toString.call()に食わせると、なんということでしょう!
var toString = Object.prototype.toString;
p(toString.call(undefined));
p(toString.call(null));
p(toString.call(false));
p(toString.call(0));
p(toString.call(''));
p(toString.call([]));
p(toString.call({}));
p(toString.call(function(){}));
p(toString.call(new Date));
p(toString.call(/[\S\s]/g));
p(toString.call(document));
p(toString.call(document.createElement('div')));
function YourOwnObject(a){
this.a = a;
};
var foo = new YourOwnObject;
p(toString.call(foo));
p(foo.constructor === Object);
p({}.constructor === Object);
ほとんどのbuilt-in objectを区別できるではありませんか。IEだとundefinedやnullやDOMなど、constructorプロパティが不在なオブジェクトがみんな[object Object]になってしまうものの、IE以外だとDOMまで嗅ぎ分けてくれます。
あとOperaだと、undefinedやnullが[object Window]になっちゃったり、Safari for iOSだと[object DOMWindow]になっちゃったり、Androidだと[object global]になっちゃったりしますが、これも何とか出来るでしょう。
built-inでないobjectもまた[object Object]と判定されてしまいますが、これはconstructorがObjectか否かをチェックすれば判別できます。
これで割とまともなtypeOf()が書ける!
というわけで、まとめると以下のとおりになります。
var toString = Object.prototype.toString;
var NU = {
'[object Object]':'IE',
'[object Window]':'Opera',
'[object DOMWindow]':'Safari iOS',
'[object global]':'Android'
};
typeOf = function(that){
var t = toString.call(that);
if (!that){
if (t in NU) {
var u = that === null ? 'Null' : 'Undefined';
return '[object ' + u + ']';
}
else return t;
}
if (t === '[object Object]') {
if (that.constructor !== Object) return null
else return t;
}
else return t;
};
[object Whatever]からWhateverだけ取り出す作業は割愛しています。
p(typeOf(undefined));
p(typeOf(null));
p(typeOf(false));
p(typeOf(0));
p(typeOf(''));
p(typeOf([]));
p(typeOf({}));
p(typeOf(function(){}));
p(typeOf(new Date));
p(typeOf(/[\S\s]/g));
p(typeOf(document));
p(typeOf(document.createElement('div')));
function YourOwnObject(a){
this.a = a;
};
var foo = new YourOwnObject;
p(typeOf(foo));
Enjoy!
Dan the JavaScripter
Posted by dankogai at 14:30│Comments(0)│TrackBack(1)
この記事へのトラックバックURL
この記事へのトラックバック
な、なんだってー!?
はてなブックマーク - kamisetoのブックマークconstructor.nameを見ればいいんじゃなの?違うのかな?
そんなおいしいプロパティなんて、あったっけ?
javascript - 関数名の取得とtypeof()の再々発明【404 Blog Not Found】at 2011年12月07日 03:40