getter/setter メソッド
オブジェクトの変数の状態について、「知る」・「設定する」の両方を行うメソッドを思いついたので、メモしておきます (まぁ多分良く知られてる方法なんだろうなとは思いますが)。
initialize: function () { this.__stack = false; }, prefer_stack: function (prefer) { return (this.__stack = prefer != undefined ? prefer : this.__stack); }
具体的にどういう事かと言いますと、一般的なジョブの処理に関して、スタックとして処理するか、キューとして処理するかを、どのように設定したり知らせたりするのが良いか、ということを考えていたんです。
で、思いついたのが上の prefer_stack というメソッドです。
引数の有無によって、スタックとして「扱いたい」という要望と、「扱いたい? (扱われたい?)」という問い合わせの両方を行っています。
代入の結果をそのまま値として利用できることを生かし、メソッドの戻り値とすることで、値の設定と返却を一文で実現できているわけです。
式の評価結果の再利用
ここからは余談になりますが、以下のようにすると一旦 true に設定してしまったら false には戻せなくなります (初期値が true である場合には、真偽値の setter としては全く無意味なものになります):
prefer_stack: function (prefer) { return (this.__stack = prefer || this.__stack); }
JavaScript には "||=" や "&&=" というロジカル・アサインメントの演算子が (まだ) 無いのでこのような形式をよく使いますね*1。用途によってはこれでも良いんじゃないかと思います。
ちなみに、論理式の評価結果は、リテラルな true/false ではなく、最後に評価された式自身の持つ値となります。例えば、"1 && 2" という演算が返す値は 2 です。
この原理により、下のような表現も可能です:
(this.callback || function (){})();
この文において this.callback と空関数はともに、式として論理演算の対象となります。そして、this.callback が既に定義されていればそれが、定義されていなければ空関数が "()" によりコールされることになるのです。これは prototype.js でも頻繁に使われているので、良く知られている形式でしょう。if 文によるテストを省略できるため、エレガントな印象がありますね*2。
*1:http://www.deepwood.net/writing/method-references.html.utf8 を参照しました
*2:ただし、この方法だと関数への参照が、レシーバ (この場合 "this") を指定せずに直接コールされてしまいます。レシーバを明示するには "(this.callback || function (){}).call(this)" のように、call か apply メソッドを利用します。