無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

オブジェクトプロパティのアクセスをフックする。

Getter,Setterを利用すると、「<オブジェクト>.<プロパティ>」でプロパティにアクセスした際に、指定した関数が実行されるようになります。注意:ただし、IEでは動作しません。

function Kitten( name ) {
  this._name = name;
}
// Getter, Setterの設定
// プロパティ名と関数を指定する。 
Kitten.prototype.__defineSetter__( "name", function(name) {
    document.getElementById("stdout").innerHTML += "set name<br/>";
    this._name = name; // this.name = name; とすると無限ループにはまるので注意
} );
Kitten.prototype.__defineGetter__( "name", function() {
    document.getElementById("stdout").innerHTML += "get name<br/>";
    return this._name;
} );

// モデルを作成。
var mii = new Kitten( "mii" );

// プロパティにアクセス
// __defineSetter__, __defineGetter__ で定義した「関数」が実行される。
mii.name = "mii"; 
var name = mii.name;

確認はこちらから

リスナ追加ユーティリティで使ってみる。

これを使えば、Modelの更新をリスンするで作ったリスナ追加ユーティリティを使う場合の制約、「モデル更新時は定義されたset()メソッドを使って更新する」必要がなくなります。モデルの更新を普通に"="で行えるようになるわけです。

/**
 * 更新リスナを追加する。
 * @param {Object} target リスナを追加するモデル
 * @param {String} key イベントキー
 * @param {Function} listener リスナ関数
 */
function addListener( target, key, listener ) {
  if ( !target.__listeners ) {

    // ターゲットを拡張する。
    target.__listeners = {}; // リスナの記録先を確保。
    
    // setterを上書き。変更を受けてリスナをキックする関数にする。
    target["_" + key] = target[key];
    target.__defineSetter__(key, function(x) { 
        this["_" + key] = x;
        if ( this.__listeners[key] ) {
            for (var i=0; i < this.__listeners[key].length; i++ ) {
              this.__listeners[key][i]( x );
           }
        }
     });
  }
  
  // リスナをターゲットの属性として追加。
  if ( !target.__listeners[key] ) {
     target.__listeners[key] = []
  }
  target.__listeners[key].push( listener  );
}


// モデル
function Kitten( name, age ) {
  this.name = name;
  this.age  = age;
  this.state = "stop";
}

// モデルを作成。
var mii = new Kitten( "mii", 1 );

// リスナを設定
addListener( mii, "state", function( state ) {
  document.getElementById("stdout1").innerHTML = state;
} );
addListener( mii, "state", function( state ) {
  document.getElementById("stdout2").innerHTML = state;
} );
addListener( mii, "state", function( state ) {
  document.getElementById("stdout3").innerHTML = state;
} );

/** コントローラー */
function KittenService( kitten ) {
  this.kitten = kitten;
}
KittenService.prototype = {
  run:  function() {
    this.kitten.state = "running"; // 普通にフィールドを更新
  },
  stop: function() {
    this.kitten.state = "stop";
  },
  jump: function() {
    this.kitten.state = "jump!";
  }
}
var service = new KittenService( mii );
service.run();

確認はこちらから

参考:Core JavaScript 1.5 Guide - ゲッタとセッタの定義