関数とthis : JavaScript

Pocket

JavaScriptのthisのメモ。

JavaScriptの関数が参照するthisの値はイベントハンドラ(イベントリスナー)とそれ以外の場合で分けて考える。

  • イベントハンドラ以外
  • イベントハンドラ

イベントハンドラ(イベントハンドラ)以外

この記事ではJavaScriptの関数を便宜上3つに分ける[1]。

  1. 関数
  2. メソッド[2]
  3. コンストラクタ[3]

関数

JavaScriptは関数を呼び出すとき自動的にthisをグローバルオブジェクトに初期化する。実行環境がブラウザならグローバルオブジェクトはwindowオブジェクトになる。

// 関数呼び出しの例
// 関数
function f() {
    console.log(this); // window : global object
}
f();



// 関数(即時実行)
(function() {
    console.log(this); // window : global object
}());



// クロージャー
function hasClosure() {
    return function() {
        console.log(this); // window : global object
    };
}
var closure = hasClosure();
closure();

メソッド

メソッドのthisはそのメソッドを持つオブジェクトを指す。

// 例1 メソッド
var o = {
    m: function() { 
        console.log(this); // Object { m=function()}
    }
}
o.m();



// 例2 メソッド
var object = (function() {
    function _m() {
        console.log(this); // Object{ m=_m() }
    };
    return {
        m: _m
    };
}());
object.m();

» jsFiddle

コンストラクタの場合

コンストラクタのthisは生成されるインスタンスを指す。

function CustomObject () {
    this.m = function() {
        console.log(this);
    }
}
var ins = new CustomObject();
ins.m(); // CustomObject { m=function()}

イベントハンドラ(イベントリスナー

イベントハンドラ(イベントリスナー)のthisはハンドラ/リスナーを設定した要素になる(event.currentTarget)。

<p id="foo">Foo</p>
<p id="bar">Bar</p>
var Foo = function() {
    this.id = 'Foo';
    this.func = function() {
        console.log(this.id); // Fooではなくfoo
    };
    document.getElementById('foo').addEventListener('click', this.func, false);
};
new Foo();
// インスタンスをthisにしたいとき
var Bar = function() {
    this.id = 'Bar';
    this.func = function() {
        console.log(this.id); // barではなくBar
    }
    document.getElementById('bar').addEventListener('click', this.func.bind(this), false);
}
new Bar();

» jsFiddle
» jsFiddle

[1] Douglas 2008は関数呼び出しを4つに分類するが、本記事ではそのうちの3つに絞っている。
Douglas Crockford著, 水野 貴明訳 2008 『JavaScript:The Cood Parts』 オライリージャパン。
[2] メソッドはオブジェクトのプロパティ。
[3] new演算子でインスタンスを作成することを想定して作成するfunction文。[1]の意味の関数と区別する意味で名前を大文字で始めることが多い。

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。