理系学生日記

おまえはいつまで学生気分なのか

任意のオブジェクトのクラス名をどうやって得るの?

ちょっと思ったんですけど,なんかよく分からんオブジェクトがあったとき,そのオブジェクトがどのクラスのオブジェクトなのか (プロトタイプを使う JavaScript に関して,オブジェクトのクラスって言い方はおかしいのかもしれないけど) ってどうやって得るんでしょうか!

Perl だと ref がその役割を果たしますし,

use LWP::UserAgent;

my $agent = LWP::UserAgent->new;
print ref $agent;  # prints "LWP::UserAgent"

c++ では typeinfo を用いて判断できる.

#include <iostream>
#include <typeinfo>

class Hoge {};
int main() {
    Hoge hoge;
    std::cout << typeid( hoge ).name() << std::endl; // prints "4Hoge"
    return 0;
}

constructor プロパティを見る

JavaScript では各オブジェクトには constructor プロパティが設定されている模様.じゃぁ,それを出力してやれば良いんじゃね?

var navi = navigator;
document.write( navi.constructor + "<br>" ); // prints "[object Navigator]"

var agent = navigator.userAgent;
document.write( agent.constructor ); // prints "function String() { [native code] }"

ふむ,一応クラス名は確認できた.

toString() を使う

toString() を使えば,まー勝手にクラス名を返してくれるようになってんじゃね?と思ってやってみた.

var navi = navigator;
document.write( navi + "<br>" ); // prints "[object Navigator]"

var agent = navigator.userAgent;
document.write( agent ); // prints "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ja-JP-mac; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3 "

Object.toString() はクラス名を返してくれるようになっていますが,当たり前ですが toString() がオーバライドされているとダメ.それに,toString() はユーザ定義型については理解できない(全て Object クラスと判断する).

サイ本を眺めてみると,オーバライドされた toString() ではなく,apply を使って Object の toString() を呼んでいた.なるほど apply を使うのか!

document.write( Object.prototype.toString.apply( navigator.userAgent ) ); // [object String]

結局,Object クラスの toString() を apply 使って呼ぶのが一番なのかな.