this→自分自身→俺→俺の物は俺の(略

今回はオブジェクト内で使われているthisについてのお話だ

thisやったじゃん。教えた内容くらい覚えておいてもらわないとねぇ

あんなものではない事を教えてやろう


今まで黙ってたけどthisって…実は、俺なんだ!

thisって自分自身なんでしょ?聞いたよ。

よしよし。では早速こいつを見てみろ

<input type="button" name="バカ" value="クリックしよう" id="button" />

 var myObj = function()
 {
  this.name = 'チルノ';
  this.init = function ()
   {
    var button = document.getElementById("button");
    // ボタンのイベントハンドラに、メソッドhelloをセット
    button.onclick = this.hello;
   }
  this.hello = function ()
  {
   alert('こんぬつあ'+this.name);
  }
 }

 var objIns = new myObj();
 objIns.init();

はいはい。こんにちわ。チル・・・はぁ!?

バカはどこから出てきた。指定されてるのはあたいの名前だけだし・・・あれ?

ボタンタグのname属性を見てみろ

いや、確かにバカって書いてあるけどさ・・・

ボタンを押して実行した時、thisはオブジェクトを指すのではなく そのボタン自体を見ていると言う事になる。

ソースを眺めるとよけいわからんだろうな。
つまりはこういう事になるんだ。

じゃぁ自分の名前を叫んでね!

自分の名前ですね!わかりました!

ようむ!!!

そりゃそうでしょ。当たり前じゃん。自分の名前を叫べって言ってるんだからさ

そうだろ。同じ事をやっているからバカって叫んだんだ。ボタンの名前はバカなんだから

理屈は分かった。でもこれじゃ使えないね。
オブジェクト終了のお知らせ

回避策がないとでも思ったか?

使えないなら、使えるようにすればいいじゃない

では、回避策についてだ。先ほどのデモでもあった通り、そのまま使えないのは不便だ
この回避策は超重要事項なので心してかかるように

どこからでもかかってきなさい

回避策の前に、thisの内容がどうなのか?
先ほどのデモにthisをalertする処理を追加した。

<input type="button" name="バカ" value="クリックしよう" id="button" />

 var myObj = function()
 {
  this.name = 'チルノ';
  this.init = function ()
   {
    var button = document.getElementById("button");
    // ボタンのイベントハンドラに、メソッドhelloをセット
    button.onclick = this.hello;
   }
  this.hello = function ()
  {
   alert('こんぬつあ'+this.name);
  }
 }

 var objIns = new myObj();
 objIns.init();

内容が違うね。

いわゆる各々のグローバルオブジェクトを指している事になる
なので、これをこんな感じに変えてやる

<input type="button" name="バカ" value="クリックしよう" id="button" />

 var myObj = function()
 {
  this.name = 'チルノ';
  this.init = function ()
   {
    var button = document.getElementById("button");
    button.onclick = this.hello;
   }
  this.hello = createDelegate(function ()
  {
   alert('こんぬつあ'+this.name);
  },this);
 }

 var objIns = new myObj();
 objIns.init();

 function createDelegate(func, thisObj)
 {
  var del = function()
  {
   return func.apply(thisObj, arguments);
  };

  del.func    = func;
  del.thisObj = thisObj;

  return del;
 }

これこそアタイの求めていた動き!

なんか変なもん追加されてるけど、解説よろしく

どうなったかを簡単に説明するとこうなる

じゃぁ自分の名前を叫んでね!

自分って言ってるけど、あんたじゃなくて、あの青いバカの事だよ

わかりました!

チルノ!!!

では、前回と変わった所をピックアップすると
1:createDelegate関数(独自関数)を追加
2:ボタンクリックで呼ばれるメソッドを丸ごとcreateDelegate関数に渡す
この2点だ

createDelegate関数だが
thisの指定先を変更させるという関数だ。

まず、引数から
第1引数:func
ここには対象となるメソッドを指定する。
第2引数:func
使いたいグローバルオブジェクトを指定する。

この関数内には、メソッドが1つと、プロパティが2つある。
まずはメソッドの中身

func.apply(thisObj, arguments);

となっている。

func…第1引数(という事になる。正確には、del内のプロパティ)
apply…Javascript関数
thisObj…第2引数(という事になる。正確には、del内のプロパティ)
arguments…Javascript関数(配列型で可変引数という意味)
である。

この関数は
対象のメソッド(func)で使用されているthisの参照先をthisObjに置き換えてやる
という動きをする。
argumentsは引数。ここになにかあれば、funcメソッドで使えるようになる。

del.func = func;
del.thisObj = thisObj;
は引数をプロパティに渡している、という事だな。

さんきゅーけーね

わかりました!どんどんやっていきましょう!

残念ながらこっち側であんたの出番予定はありません。

みょん!?ホントですか!?

事実です。

チッ!
さりげなく入るの失敗した!いつか例の中で大暴れしてやるぞ!