this (プログラミング)
this
は、プログラミング言語に出てくる概念のひとつで、自身の動いているオブジェクトを指す予約語。主にインスタンスメソッド内で使用される。this
の他にself
、Me
といった語を使う言語もあるが、言語を問わず概念は共通しているので、以下ではthis
で代表させて記述することとする。
概要
[編集]this
は現在のオブジェクトを指した参照、あるいはポインタであり、たいていの場合は変更不可能である。
オブジェクトが生成すると、this
への参照はつねに有効なものとなる。これは明示的に参照しなければならない言語もあれば、静的スコープで暗黙のうちに解決している言語もある。ただし、this
を暗黙のうちに解決する言語でも、明示的にthis
を必要とする場面(ローカル変数で隠蔽されている同名のメンバー変数を参照する場合や、自身への参照を返り値とする場合など)もある。
this
はメソッドへの引数となっている。例えば、C++で書いた以下のようなメソッドは、
int foo::print (bar x)
本質的にはC言語での以下のような呼び出しに相当している。
int foo_print (foo *const this, bar x)
PythonやPerl 5など、言語によってはthis
をメソッドへの1つ目の引数として明記する必要がある。この引数の名前をthis
やself
とする必然性はなく、他の引数と同様にどんな名前を付けても文法上問題はない。ただし、通常の場合、PythonやPerlでは慣習的にself
が使われる。
GCCなど、一部のC++コンパイラでは、this
を引数に明示することで、その型を別なポインタに変えることができる[1]。
C++やJavaでの静的メソッドはインスタンスに対応せずクラスに所属するものであるため、this
は使えない。Python、Ruby、Smalltalk、Objective-Cなどでは、「クラスオブジェクト」のメソッド(クラスメソッド)となっていて、this
はクラスオブジェクトを指す。
言語ごとの事情
[編集]C++
[編集]初期のバージョンの C++ ではthis
を変更でき、メソッド内から動作するオブジェクトを切り替えることができたが、のちに不可能となり、this
は右辺値となっている[2]。
初期の C++ には参照がなかったが、もし最初から参照があったとしたら、this
はポインタではなく参照となっていたであろう[3]。
C++ では、delete this
とすることで、オブジェクトが自ら消えることができる。
C#
[編集]C# では、this
は現在のインスタンスのメンバーを参照するのに用いられる。
特徴的な点として、C#の値型ではメンバー参照に加え、this
を代入式の左辺に置いて自分自身の値を書き換えることができる。
C#7.2で追加されたreadonly構造体では、このthis
の書き換えを禁止できる。
struct MyStruct {
// 読み取り専用フィールド
public readonly int Num;
public MyStruct(int num) {
Num = num;
}
public void ChangeThis() {
// 自分自身を書き換える
// フィールドは読み取り専用にもかかわらず、全体が書き換わる
this = new MyStruct(Num + 1);
}
}
// readonly構造体ではこの書き換えはできない。
readonly struct MyStruct {
// ...
}
Dylan
[編集]Dylan では多重ディスパッチが行われ、this
という概念がないが、メッセージをあるオブジェクトに送るという意識は文法に残っている。下に示した2つの記法は糖衣構文であり、同等に動作する。
object.method(param1, param2)
method (object, param1, param2)
Java
[編集]Java では、this
は現在のインスタンスを指すキーワードであり、クラスの値やメソッドを参照するのに用いられる。Java ではインスタンスメソッドがすべて仮想メソッドなので、this
が null
となることはない。
JavaScript
[編集]プロトタイプベースオブジェクト指向言語である JavaScript では、関数はオブジェクトに属している(メソッドである)ことも、属さないでいる(ただの関数である)こともできる。したがって、this
が何を指しているかは、関数の呼び出し方によって異なっている。
多くの場面では、クラスベースオブジェクト指向言語の this
と同じように使うことができる。たとえば、
object.notify = function () { alert (this); };
object.notify();
のように関数(object.notify
)をメソッドとして呼び出した場合、this
はobject
を指す。また、
Counter = function () { this.counter_value = 0; };
c = new Counter();
のように new
を付けて関数(Counter
)をコンストラクタとして呼び出した場合、this
は新しく生成されるオブジェクトを指す[4]。
関数を単独で呼び出す場合は、this
はstrict-mode中であればundefined
であり、そうでなければグローバルオブジェクトを指すが、this
が何を指すかを個別に指定して呼び出すこともできる。(Function.prototype.apply
) [5]。
Object Pascal
[編集]Object Pascal では self
が使われる。
Objective-C
[編集]Objective-C では self
が使われる。
PHP
[編集]PHPでは、this
が使われる。
Python
[編集]Python では、this
は文法上の予約語ではないが、自動的に対象となるオブジェクトが渡される、メンバ関数の1つ目の引数となっている。慣習的に、この引数の名前としてself
が使われる。classmethod
修飾子を付けて定義されたクラスメソッドでは、1つ目の引数にクラスオブジェクトそのものが渡される。staticmethod
修飾子を付けて作られた静的メソッドでは、1つ目の引数に何かが自動的に渡されることはない。
Ruby
[編集]Ruby では self
が使われる。
Self
[編集]Self 言語は、「self
」が使われることが名前の由来となっている。
Smalltalk
[編集]Smalltalk では self
が使われる。
Visual Basic
[編集]Visual Basicでは Me
が使われる。
脚注
[編集]- ^ Bound member functions - Using the GNU Compiler Collection (GCC)
- ^ ISO/IEC 14882:2003(E): Programming Languages - C++. ISO/IEC. (2003)
- ^ Stroustrup: C++ Style and Technique FAQ
- ^ 山田祥寛 (2007年9月25日). “連載:Ajax時代のJavaScriptプログラミング再入門 第4回 JavaScript でオブジェクト指向プログラミング Page1”. @IT. 2011年12月13日閲覧。
- ^ 太田昌吾 (2010年10月12日). “これでできる! クロスブラウザJavaScript入門 第16回 JavaScriptの
this
とcall
”. 技術評論社. 2011年12月16日閲覧。
外部リンク
[編集]- The Design and Evolution of C++ by Bjarne Stroustrup - Addison-Wesley Pub Co; 1st edition (March 29, 1994); ISBN 0-201-54330-3
- More Effective C++: 35 New Ways to Improve Your Programs and Designs by Scott Meyers -- (1995) ISBN 0-201-63371-X
- Java this