理系学生日記

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

オブジェクトの型変換フロー

数値コンテキストにおいて,オブジェクトからプリミティブ型への変換がどう行われるのかについて,ちょっと確かめてみたりしたのでした.

var obj = { 
    toString: function () { return "hello world"; },
    valueOf:  function () { alert( "valueOf" ); return this; }
};

var ans = 1 + obj;
alert( ans );

これを実行すると,"valueOf" と書かれたアラートが表示され,その次に "1hello world" と書かれたアラートが表示される.


ECMAScript の仕様によると,数値コンテキストにおける オブジェクトの型変換は次のように行われるみたい.

O の DefaultValue メソッドがヒント Number で呼出されると、次のステップが取られる:
1. O の Get メソッドを、引数 "valueOf" で呼出す。
2. Result(1) がオブジェクトでなければ、ステップ 5 へ。
3. Result(1) の Call メソッドを、this 値 O と空の引数のリストで呼出す。
4. Result(3) がプリミティブ値であれば、Result(3) を返す。
5. O の Get メソッドを、引数 "toString" で呼出す。
6. Result(5) がオブジェクトでなければ、ステップ 9 へ。
7. Result(5) の Call メソッドを、this 値 O と空の引数のリストで呼出す。
8. Result(7) がプリミティブ値であれば、 Result(7) を返す。
9. 例外 TypeError を投げる。

This Document has Moved

だから,もし toString() がプリミティブ型を返さないと例外になるはずだな.

var obj = { 
    toString: function () { return this; },
    valueOf:  function () { alert( "valueOf" ); return this; }
};

var ans = 1 + obj;
alert( ans );

上のを実行すると,エラーコンソールに次のメッセージが出力された.

エラー: can't convert obj to primitive type

なるほど.なるほど.