あるオブジェクトのメソッドで自身のプロパティを参照する場合。
run1とrun2のどちらにするか迷う。
var o = {
prop: 1,
run1: function(){
this.prop
},
run2: function(){
o.prop
}
}
世間ではthisを使っている人が多いと感じる。
見やすいので私は変数名を使いたい。
thisの場合の特徴
- thisの参照が変わってしまう
- thisが何を指すか分かりにくい
- コンストラクター + prototypeに変えやすい
- オブジェクトの構造を変えやすい
- 直接実行できる
1, 2の欠点が大きいので、thisは継承以外では使わないように、とどこかで見たような気がするが・・・これしか見つからなかった。しかしこれは特定のコンパイル向けの説明。
To prevent property flattening from breaking your references to this, only use this within constructors and prototype methods. The meaning of this is unambiguous when you call a constructor with the new keyword, or within a function that is a property of a prototype.
Understanding the Restrictions Imposed by the Closure Compiler - Closure Tools — Google Developers の一番下
一方でGoogle JavaScript Style Guideでは使ってもよいと書いてあったり
Because this is so easy to get wrong, limit its use to those places where it is required:
- in constructors
- in methods of objects (including in the creation of closures)
1. thisの参照が変わってしまう
setTimeoutなど。
-> bind, callなどを使う手がある
2. thisが何を指すか分かりにくい
コメント書いてほしい!
-> でもコメント書いても実行されるコンテキストで変わってしまう...
3. コンストラクター + prototypeに変えやすい
設計段階ではただのオブジェクトで書いて、あとから書き換えるときに。
prototype以下を修正無しでそのまま使える。
function Klass(prop){
this.prop = prop
}
Klass.prototype.run = function() { //変更不要
this.prop
}
4. オブジェクトの構造を変えやすい
- 変数名をoではなくmyObjにリネーム
var myObj = {
prop: 1,
run1: function() {
this.prop // そのままでOK
},
run2: function() {
o.prop // 要変更 => myObj.prop
}
}
- 上位のオブジェクトの中に入れる場合
var parentObj = {
o: {
prop: 1,
run1: function() {
this.prop // そのままでOK
},
run2: function() {
o.prop // 要変更 => parentObj.o.prop
}
}
}
読みやすさとリネームの手間のどちらを取るか(リネームは簡単に行えるのけども)。
しかし、こうする手もある。
(function(o) {
o.run2()
})(parentObj.o) // <- 階層が深いとここが面倒?
5. 直接実行できる
*利点なのか疑問
({
prop: 1,
run1: function() {
this.prop
}
}).run1()
まとめ
5以外は、this/変数名どちらを使ってもそれぞれの問題に対応する術はある。
変数名: わかりやすい
this: 固定する方法があり、汎用性が高い
(´-`).。oO( 結局どちらにしたら良いのじゃろう。なぜthisを使う人が多いのだろう。 )