valueOf
無駄ではありません。これにより、がプリミティブ型Object
を期待する式に値を提供できるようになります。AS3とJavaScriptで利用できます。
誰かが int を取る関数を書いた場合、それをオブジェクトに渡すことができます (より正確には、オブジェクトのvalueOf()
関数の結果を渡します)。
有用性は、1) オブジェクトが渡されないため、最も外側のスコープ内のオブジェクトであるという事実、および 2) 読み取り専用操作であり、割り当てを行うことができないという事実によって緩和されます。
ここに私の頭の上から離れたいくつかの具体的な例があります:
例 1:Counter
読み取られるたびに値が自動的にインクリメントされるクラス:
class Counter
{
private var _cnt:int = 0;
public function Counter() { }
public function valueOf():int
{
return _cnt++;
}
public function toString():String { return ""+valueOf(); }
}
使用法:
var c:* = new Counter();
trace(c); // 0
trace(c); // 1
trace(2*c+c); // 2*2+3 = 7
trace(c); // 4
ノート:
- 関数は を優先する
toString()
ため、パススルーを追加しました。String
toString
valueOf
- c は * ではなく として入力する必要があり
Counter
ます。そうしないと、Counter to Number の暗黙の強制に関するコンパイラ エラーが発生します。
例 2: (読み取り専用) ポインター型
int の配列があり、配列内の要素への参照 (別名ポインター) が必要だとします。ECMA スクリプトにはポインターがありませんが、次の方法でエミュレートできますvalueOf()
。
class ArrayIntPointer
{
private var arr:Array;
private var idx:int;
public function ArrayIntPointer(arr:Array,
idx:int)
{
this.arr = arr;
this.idx = idx;
}
public function valueOf():int
{
return arr[idx];
}
public function toString():String { return ""+valueOf(); }
}
使用法:
var arr:Array = [1, 2, 3, 4, 5];
var int_ptr:* = new ArrayIntPointer(arr, 2);
// int_ptr is a pointer to the third item in the array and
// can be used in place of an int thanks to valueOf()
trace(int_ptr); // 3
var val:int = 2*int_ptr+1;
trace(val); // 7
// but it's still an object with references, so I
// can change the underlying Array, nand now my
// object's primitive (aka, non-Object types) value
// is 50, and it still can be used in place of an int.
arr[2] = 50;
trace(int_ptr); // 50
// you can assign int_ptr, but sadly, this doesn't
// affect the array.
それはかなり滑らかです。ポインターを割り当てて配列に影響を与えることができれば非常に便利ですが、int_ptr
代わりに変数を割り当てるため、残念ながらそれは不可能です。そのため、読み取り専用ポインターと呼んでいます。