これがJavaScriptの動作方法であるため、動作しません。コンストラクター関数内で関数を宣言するだけでは、コンストラクター関数によって作成されたオブジェクトに設定されません。オブジェクトと関数の間のリンクを明示的に(オブジェクトに割り当てることによって直接、またはより多くの場合は間接的に)作成する必要があります。プロトタイプ)。
これを行う一般的な方法は、プロトタイプの継承を使用することですが、関数を個々のオブジェクトに直接割り当てることもできます(ただし、「メンバー関数」について説明しました。JavaScriptでそのようなことを行う一般的な方法は、プロトタイプを使用することです)。 。
プロトタイプの継承を設定するには、いくつかの方法があります。従来のブラウザでも幅広いJavaScriptエンジンと互換性のある古典的な方法はprototype
、オブジェクトを参照するコンストラクター関数のプロパティを使用することです。そのオブジェクトは、を介して作成されたインスタンスのプロトタイプになりますnew FunctionName
。そのオブジェクトにプロパティを追加して、その関数によって作成されたインスタンス間でプロパティを共有します。
したがって、プロトタイプの継承を使用すると、次のようになります。
function Init(name) {
this.name = name;
}
Init.prototype.displayName = function() {
alert(this.name);
};
var i = new Init("Mozilla");
i.displayName();
上記に関する注意:
JavaScriptでは、コンストラクター関数は大文字で始まるという圧倒的な慣習があります。だから私はでInit
はなくそれを呼んだinit
。
すべての関数にprototype
は、空白のオブジェクトであるプロパティが自動的にあります。
関数を参照するというプロパティをそのオブジェクトに追加しますdisplayName
。
名前をハードコーディングするのではなくInit
、引数として渡します。
新しく構築されたインスタンスのプロパティに名前を保存していることに注意してください。の呼び出し内でInit
、そのインスタンスはとして使用できますthis
。
同様に、displayName
はオブジェクトから関数参照を取得する式の一部として呼び出されるため、this
はへの呼び出し内のオブジェクトであり、displayName
そのためthis.name
に名前が付けられます。
上記のことを簡単にするために、無名関数をに割り当てましたdisplayName
。(プロパティには名前がありますが、関数には名前がありません。)実際のコードではそうしない傾向があります。
を介して構築されたすべてのインスタンスは、プロトタイプを介して関数new Init
の同じコピーを共有します。displayName
もっと探検する(私のブログで):
JavaScript(および階層)でオブジェクトのクラスを構築することに興味がある場合は、私のLineage
ツールキットにも興味があるかもしれません。
ES5の時点で、別のオプションがありますObject.create
。これにより、コンストラクター関数を使用せずに、オブジェクトを作成してプロトタイプを直接割り当てることができます。ただし、new
コンストラクター関数を使用していることを意味するを使用したので、これについては詳しく説明しません。
これで、必要がなければJavaScriptのプロトタイプ機能を使用する必要はありません。たとえば、次のようにすることができます。
function Init(name) {
var name = name;
this.displayName = function() {
alert(name);
};
}
var i = new Init("Mozilla");
i.displayName();
これはJavaScriptのプロトタイプ機能を使用せず、代わりに、displayName
呼び出すたびに新しい関数を作成し、Init
それをオブジェクトに直接割り当てます。(妥当な品質のJavaScriptエンジンは、関数のコードを再利用するのに十分スマートですが、インスタンスごとに異なる関数オブジェクトがあります)。上記では、name
プロパティを完全にプライベートにします。これは、各呼び出しで作成する関数がローカル変数のクロージャーname
であるためです。(詳細:閉鎖は複雑ではありません)