- メソッド呼び出しパターン
- 関数呼び出しパターン
- コンストラクタ呼び出しパターン
- apply 呼び出しパターン
このうち、コンストラクタ呼び出しの際の関数呼び出しパターン(?)について。
パブリックメソッドからプライベートなメソッドを呼びたい場合、javascript をあまり知らない java 使いだとこう(↓)書いてしまうと思う。
var msg = 'global hello'; var Test = function() { this.msg = 'hello'; this.say = function() { print(this.msg); // => hello func_say(); } function func_say() { print(this.msg); // => global hello } } var t = new Test(); t.say();
でもこれ、 func_say() の中の this はグローバル変数を指しているので this.msg は 'global hello' を参照することになる。global な msg が無い場合は undefined になるからなんで?ってなる。
func_say に this をつければメンバ変数にアクセスできるけど、呼び出す側も this をつけないと global な func_say を呼び出してしまう落とし穴。
var msg = 'global hello'; function func_say() { print('global func_say'); } var Test = function() { this.msg = 'hello'; this.say = function() { print(this.msg); this.func_say(); // => hello } this.func_say = function() { print(this.msg); // => hello } } var t = new Test(); t.say();
java を書くときには "なるべく private なメソッドからインスタンス変数にアクセスしない" という自分ルールを作っていて、これに従えば
var Test = function() { this.msg = 'hello'; this.say = function() { print(this.msg); func_say(this.msg); } function func_say(msg) { print(msg); } } var t = new Test(); t.say();
と書けるので一番ミスが少ないと思う。
やっぱりアクセスしたい場合は魔法を使う。
var Test = function() { var that = this; // ★ this.msg = 'hello'; this.say = function() { print(this.msg); func_say(); } function func_say(msg) { print(that.msg); // ★ } } var t = new Test(); t.say();
this を that に置き換える。that が一般的らしいけど何を指しているのかよく分からないので self にしてみる。
var Test = function() { var self = this; this.msg = 'hello'; this.say = function() { print(self.msg); func_say(); } function func_say(msg) { print(self.msg); } } var t = new Test(); t.say();
こっちの方が事故が少ないのではないかという考えに至る。
これでも、パブリックメソッドからパブリックメソッドを呼ぶときに slef をつけないと事故る可能性がある。java を書くときはカッコ悪いという理由で書いてないし。
いい方法が無いものか。