JavaScript の this

JavaScript の this の挙動なのですが、オブジェクトと絡めてはまったのでメモしておきます。

自分は普段 jquery を使うのですが、例えば $('a').click({function})といった形式を使う場合。この function に特定のオブジェクトのメソッドを指定していたのですね。こうした場合、 function オブジェクトがイベントリスナー(?)に参照渡しされるようです。こうすると、渡した関数の中で this を使っていると変な挙動になります。

JavaScript の this は呼び出しのコンテキストによって参照先が変わるからです。詳しく仕様書を見ていないので言い切る事はできませんが、基本的に this は呼び出し時のレシーバを指すようです。

obj_one = { prop: 'value 1' }
obj_two = { prop: 'value 2' }

function return_prop()
  {
    return this.prop
  }

obj_one.get_prop = return_prop;
obj_two.get_prop = return_prop;

obj_one.get_prop();  // 'value 1' が帰る
obj_two.get_prop();  // 'value 2' が帰る

上記の例で "this" の参照先が変わっているのが分かったと思います。

例2: オブジェクト指向の場合

function obj_one_const()
  {
    this.prop = 'value 1';
    
    this.get_prop = function()
      {
        return this.prop;
      }
  }
var obj_one = new obj_one_const();

obj_two =
  {
    prop: 'value 2'
  }
obj_two.get_prop = obj_one.get_prop;

obj_one.get_prop();  // 'value 1' が帰る
obj_two.get_prop();  // 'value 2' が帰る

上記の例でも this の参照先が変わっています。レシーバを指しているのは変わりません。

で、イベントリスナーに関数を登録する場合はこうするわけです。

 $('a').click(get_prop)

こうなると、リスナーに登録された状態の関数オブジェクトは、リスナーがその関数オブジェクトをどう呼び出すかによって this の参照先が変わってしまう。

JavaScript によるオブジェクト指向を利用している場合は、オブジェクトのメソッドをリスナーに登録する形になりますが、this が「そのオブジェクト」を指すとは限らなくなってしまう。こうなると、そのオブジェクトやプロパティに対する操作を期待して this を利用できなくなってしまうのですね。

こうした場合にはクロージャの機構を利用すると良いみたいです。
以下の例は別に this 使う必要なくなってるんですが(笑)、挙動確認のためということで。

function obj_one_const() {
  this.prop = 'value 1';
  var prop = this.prop;

  function get_prop = function()
    {
      return prop;
    }
}
obj_one = new obj_one_const();

obj_two =
  {
    this.prop = 'valeu 2';
  }
obj_two.get_prop = obj_one.get_prop;

obj_one.get_prop();  // 'value 1' が帰る
obj_two.get_prop();  // 'value 1' が帰る

最初は戸惑いましたが、慣れてくると面白いです。メジャーなオブジェクト指向よりも、こちらのオブジェクト指向のほうが「組み立ててる感」が強いですね。

最近こっち方面の動向チェックできてないんだよな。このへんって常識なのかなぁ(笑