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' が帰る
最初は戸惑いましたが、慣れてくると面白いです。メジャーなオブジェクト指向よりも、こちらのオブジェクト指向のほうが「組み立ててる感」が強いですね。
最近こっち方面の動向チェックできてないんだよな。このへんって常識なのかなぁ(笑