設計ミスの結果、あるオブジェクトのメソッドにおいて、処理の一部を内部関数に担当させる、といったことができなくなった。なぜなら、呼び出された内部関数では、this に間違った値が設定されてしまっており、呼び出し元のメソッドと、thisオブジェクトくを共有できないからだ。
- p.33 4.3.2 関数呼び出しパターン -
一度読んだだけではよく分からなかったけど、以下のコードを書いて理解。内部関数内で this は global な this になってしまう(設計ミスの結果)。通例で that という名前の変数を定義して this を突っ込む。that 経由でアクセスすると内部変数にアクセスすることができる。
// グローバルな値 var value = "999"; var myObject = { value: 0, // 内部変数 increment: function(inc) { this.value += typeof inc === 'number' ? inc : 1; }, add: function(a,b) { return a + b; } } myObject.double = function() { var that = this; // myObject の変数が参照される print("this.value@double is " + this.value); //=> 3 print("that.value@double is " + that.value); //=> 3 var helper = function() { // that を経由することでmyObject 内の add にアクセスできる。 that.value = that.add(that.value , that.value); // ここでの this は global なのでトップレベルの変数が参照される print("this.value@helper@double is " + this.value); //=> 999 // that を経由すると myObject 内の変数を参照できる。 print("that.value@helper@double is " + that.value); //=> 6 }; helper(); }; myObject.increment(); myObject.increment(2); myObject.double(); print("this.value@global is " + this.value); //=> 999
仕様は分かったけど、なんで that 経由なら OK なのかが良く分からない・・・。
内部関数から this.hoge にアクセスする場合は関数も this.func と定義しないとダメなんだと思っていたけど、これは激しく勘違だったってことが分かった orz