__defineSetter__, __defineGetter__

__defineSetter__ と __defineGetter__ ( https://developer.mozilla.org/ja/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineGetter , https://developer.mozilla.org/ja/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineSetter ) を使ってみようと思って書いたコードが以下。 closure と併用してガチガチに capsulation するくらいしか思いつかなかったんだけど今のおれでは Factory 経由で閉じ込める以下の方法が限界だった。もっとスマートに書けるかな ?

それぞれのうまみは以下のような感じ ?

  • __defineSetter__
    • C++ でいう operator= の overwride ?
    • 値の初期化 / 代入時にチェックができる。
    • 複数の変数に代入ができる。
  • __defineGetter__
    • scope chain の先頭以外の値を参照して返す値を決定できる。結果的に closure との併用で capsulation がラク
    • 値の集約 ( 複素数を実数部虚数部まとめて返すとか ) ができる。ただ、これは method 定義でもできるので特有のうまみじゃない。
function SpecialNumberFactory() {
    let even, prime;

    function SpecialNumber() {};
    SpecialNumber.prototype.__defineGetter__(
        'even',
        function () even
    );
    SpecialNumber.prototype.__defineSetter__(
        'even',
        function (val) {
            if (typeof val !== 'number') throw new Error('not number!');
            if (val % 2 !== 0) throw new Error('not even number!');
            even = val;
            return even;
        }
    );
    SpecialNumber.prototype.__defineGetter__(
        'prime',
        function () prime
    );
    SpecialNumber.prototype.__defineSetter__(
        'prime',
        function (val) {
            if (typeof val !== 'number') throw new Error('not number!');
            for (let i=2, l=val ; i<l ; ++i)
                if (val % i === 0) throw new Error('not prime number!');
            prime = val;
            return prime;
        }
    );
    return new SpecialNumber();
}