JavaScriptの「this」を「HUNTER×HUNTER」で理解

本記事は下記を参考に漫画、「HUNTER×HUNTER」に置き換えながら説明する内容となっております。誤字脱字、間違い等ありましたらコメントを頂けますと幸いでございます。
[JavaScriptの「this」は「4種類」？？](http://qiita.com/takeharu/items/9935ce476a17d6258e27)

#javascriptの「this」は「念能力者」？？
この記事ではベースとなる４種類の「this」を念能力者として紹介します。
念能力者を理解できれば他もすぐに理解できます。

#thisの４種類のパターン
１：メソッド呼び出しパターン（キャラの自己紹介）
２：関数呼び出しパターン（パクノダで考えよう）
３：コンストラクタ呼び出しパターン（具現化系能力者で考えよう）
４：apply,call呼び出しパターン（クロロ=ルシルフルで考えよう）

#メソッド呼び出しパターン（キャラの自己紹介）
メソッド呼び出しパターンはキャラの自己紹介

```javascript:メソッド呼び出しパターン
var ゴン=フリークス = {
  系統: '強化系',
  念能力: 'ジャジャン拳',
  系統の種類: function() {
    console.log(this.系統);
  }
}
ゴン=フリークス.系統の種類(); // 強化系
```

かなり直感的でわかりやすいですね！
ポイントとして
**ゴン=フリークスの名前の「=」をプログラムで使用する「=」と勘違いしない事です！**

#関数呼び出しパターン（パクノダで考えよう）
関数とメソッド、二つの呼び方を比較

```javascript
ビスケット＝クルーガー.系統の種類(); // メソッド呼び出し
系統の種類(); // 関数呼び出し
```

「.」で呼ばれているかどうかの違いのみですね。

では関数呼び出しパターンの「this」はいかに…
'use strict';を使用した場合、undefinedとなります。

```javascript:関数呼び出しパターン
'use strict';
function 系統の種類() {
  this.系統 = '変化系';
  console.log(this.系統); //注１
}
系統の種類(); // Cannot set property '系統' of undefined
```

この場合は「this」は「グローバルオブジェクト」を指してしまいます。

パクノダにthisと接触してもらわないと、thisの原記憶の情報はありません。（未定義の状態）

内部関数でローカル変数を参照する。
パクノダの能力を使用して、thisに接触してself領域に記憶させましょう。

```javascript:関数呼び出しパターン
var ビスケット＝クルーガー = {
  系統: '変化系',
  系統の種類: function() {
    var self = this;
    console.log(self.系統); // 1
  
    function 系統の種類() {
      console.log(self.系統); // 1
    }
    系統の種類();
  }
};
ビスケット＝クルーガー.系統の種類(); // 変化系 変化系
```

「this」を別の変数で持っておきます。この手法はよく使われます。
慣用的に変数は「self」, 「that」, 「_this」のどれかが使われる事が多いです。

ポイントとしては、この一行をパクノダと考えることが大事です。

```
var self = this;
```

#コンストラクタ呼び出しパターン（具現化系能力者で考えよう）
次はコンストラクタ呼び出しパターンです。
（基記事ではインクリメント処理（加算処理）しているので、原作ではありえない例えとします）

```javascript:コンストラクタ呼び出しパターン
function 具現化(具現化する物質) {
  this.具現化した物質 = 具現化する物質;
  this.具現化した物質を増やす = function() {
    this.具現化した物質　+　具現化した物質;
  };
}
var シズク = new 具現化(デメちゃん);
console.log(シズク.具現化した物質); // デメちゃん　1つ

シズク.具現化した物質を増やす();

console.log(シズク.具現化した物質); // デメちゃん　2つ
```

HUNTER×HUNTERだと超絶分かりやすいですね！
「new」をつけると実態を生成できるので、具現化系能力者が物質を具現化した事になりますね。

パフォーマンスを考えるとメソッドは下記、書き方がよろしいかと

```javascript:コンストラクタ呼び出しパターン
function 具現化(具現化する物質) {
  this.具現化した物質 = 具現化する物質;
}
具現化.prototype.具現化した物質を増やす = function() {
  this.具現化した物質　+　具現化した物質;
};
```

「new」を使用するとたくさんの具現化系能力者を生成できますね。

```javascript:コンストラクタ呼び出しパターン
var クラピカ = new 具現化(鎖);
var カイト = new 具現化(気狂いピエロ);
var ツボネ = new 具現化(大和撫子七変化);
```

#apply,call呼び出しパターン（クロロ=ルシルフルで考えよう）
これは他のオブジェクトのメソッドを自分のメソッドのように使用することができます。

つまり、クロロ=ルシルフルは一定の条件を満たすと人の能力は使用できるようになりますが、apply,callはその条件を無視して他の念能力使えるようになります。

```javascript:apply,call呼び出しパターン
var シャルナーク = {
  系統: '操作系',
  系統の種類: function() {
    console.log(this.系統);
  },
  念能力: function() {
    console.log('携帯する他人の運命（ブラックボイス）');
  }
};
var クロロ=ルシルフル = {
  系統: '特質系'
};

シャルナーク.系統(); // 操作系

シャルナーク.系統.apply(クロロ=ルシルフル); // 特質系
シャルナーク.系統.call(クロロ=ルシルフル); // 特質系

シャルナーク.念能力.apply(クロロ=ルシルフル); // 携帯する他人の運命（ブラックボイス）
シャルナーク.念能力.call(クロロ=ルシルフル); // 携帯する他人の運命（ブラックボイス）
```

「apply」と「call」を使うと「強制的にthisを束縛」できます。
「apply」と「call」の第一引数は「this」にsetしたいオブジェクトです。

「apply」と「call」の違いは基記事を参照してください。

#まとめ
覚えることは「this」ではなく念能力者についてです。

変数や関数を日本語で使用することはありませんが、分かりやすくするために使用しています。
あくまで理解を促すための資料です。

若干無理やり落とし込んだ箇所もあったかと思いますが少しでも楽しく学べた方がいましたら幸いです。