JSでハッシュのキーにオブジェクトを使ってみる
それなりブログ さんのこちらの エントリー にて、 JavaScript でハッシュのキーにオブジェクトがそのまま使えるか?を実験されてたので、自分でもやってみた。
var foo = new String('foo');
var bar = new String('bar');
alert(typeof foo); // ---> object
alert(typeof bar); // ---> object
var Hash = {};
Hash[foo] = 1;
Hash[bar] = 2;
for (var i in Hash)
{
alert(typeof i); // 2回とも string
}
なるほど。そもそも方変換されてる訳ね。じゃあ、どうやって型変換してる?と思い、とりあえず toString をオーバーライドしてみる。
var foo = new String('foo');
var bar = new String('bar');
foo.toString = function ()
{
alert('hello');
return this;
}
bar.toString = function ()
{
alert('world.');
return this;
}
var Hash = {};
Hash[foo] = 1; // ---> ココで hello
Hash[bar] = 2; // ---> ココで world.
for (var i in Hash)
{
alert(i); // ---> ココはfoo, bar
}
やっぱココか。
ちなみにコレ、 toString の返り値をHOGEとかにすると、ちゃんと for の中ではHOGEって出るね。(当たり前か。)でも、1個だけしっくり来なかった事があった。
foo.toString = function ()
{
return this;
}
これだとエラーは出ない。でも、
foo.toString = function ()
{
return this.toUpperCase();
}
これだと Firebug で見ると too much recursion なエラーを吐く。どこかで型変換してるってことは再帰的に回ってるのは同じだと思うんだけど。違うのかね?
ココまで色々試してて自分なりに出した結論としては、 window.foo と window.Hash.foo は名前空間が違うんだから別物で当たり前なのかな?でした。
奥が深いね。 JavaScript は。
以下、思い出した余談。
var foo = new String('foo');
var bar = 'bar';
alert(typeof foo); // ---> object
alert(typeof bar); // ---> string
var hoge = false;
var hige = new Boolean(false);
// コレはfalseがアラートされる。
if (hoge)
{
alert('true');
}
else
{
alert('false');
}
// コレはtrueがアラートされる!
if (hige)
{
alert('true');
}
else
{
alert('false');
}
普通に書いてる間は Boolean なんて new しないけどね。
- Posted at:
- 2007/06/08 02:19:28
- 4 Comments
- 0 TrackBacks
- Tags:
- JavaScript
- Trackback:
- http://humming.via-kitchen.com/2007/06/08/tried-to-use-object-as-hash-key-in-js/trackback/
TrackBacks
まだ登録されていません。
Comments
kjirou
とても為になりました。ありがとうございます。
そもそも、new String("foo"); と "foo"; に違いが生じていることがわかりません。
"foo"の記法は、Stringオブジェクト生成のための、単なるシンタックスシュガーのはずだから、中身は同じの方がわかりやすいよな?と思ってます。
ちなみに hoge -> hige -> hage スか?
nobu
なんで変わってしまうんでしょうね。
コンストラクタとかが噛んでるんでしょうか?
ちなみに hoge -> hige -> hage です。
javascripter
new String("foo")と"foo"は別のものです。シンタックスシュガーではありません。
new Stringはプリミティブ値のラッパーオブジェクトで、new String("foo").valueOf()でプリミティブな"foo"を取り出すことができます。
foo.toString = function ()
{
return this.toUpperCase();
}
が無限再帰する件は、"foo"に対してtoStringを呼んだ時に暗黙的にString型のインスタンスに変換され、.toUpperCaseする時にもう一度toStringが呼ばれるからです。
javascripter
new String("foo")と"foo"は別のものです。シンタックスシュガーではありません。
new Stringはプリミティブ値のラッパーオブジェクトで、new String("foo").valueOf()でプリミティブな"foo"を取り出すことができます。
foo.toString = function ()
{
return this.toUpperCase();
}
が無限再帰する件は、"foo"に対してtoStringを呼んだ時に暗黙的にString型のインスタンスに変換され、.toUpperCaseする時にもう一度toStringが呼ばれるからです。