16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

オブジェクト自身を参照する際に、thisと変数名のどちらを使うか

Posted at

あるオブジェクトのメソッドで自身のプロパティを参照する場合。
run1とrun2のどちらにするか迷う。

var o = {
  prop: 1,
  run1: function(){
    this.prop
  },
  run2: function(){
    o.prop
  }
}

世間ではthisを使っている人が多いと感じる。
見やすいので私は変数名を使いたい。

thisの場合の特徴

  1. thisの参照が変わってしまう
  2. thisが何を指すか分かりにくい
  3. コンストラクター + prototypeに変えやすい
  4. オブジェクトの構造を変えやすい
  5. 直接実行できる

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を使う人が多いのだろう。 )

16
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?