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 メソッドを利用します。