ここで、m_first と m_second は class1 の 2 つのプライベート インスタンス フィールド、method1 と method2 は 2 つのプライベート インスタンス メソッドです。これらは、このクラスのオブジェクト内でのみ使用でき、オブジェクトの外では使用できません。
ここでは、プライベート メソッドを作成するには 2 つの方法があることがわかります。1 つはクラス内で直接メソッドを定義する方法で、もう 1 つは最初にローカル変数 (プライベート インスタンス フィールド) を定義してから匿名メソッドを定義する方法です。値を割り当てます。
クラス内でメソッドを直接定義する場合、メソッドのスコープはこのクラスであるため、このメソッドはこのクラスの外部からアクセスできません。また、クラス内のすべてのプライベート インスタンス フィールドにアクセスできます。これにより、これはプライベートであることが保証されます。インスタンスメソッド。
1. コンストラクター コードは、クラス定義全体の最後に配置する必要があります。これは、その中で呼び出されるすべてのメソッドが確実に終了するようにするためです。定義されています。 JavaScript はインタープリタ言語であるため、上から順に実行されます。そのため、コンストラクターのコードが他のメソッド定義の前に配置されると、呼び出しステートメントが実行されたときに呼び出されるメソッドが見つかりません。間違ってしまいました。
2. { } によって作成されたブロックはスコープを変更しないことがすでにわかっているため、このようなコンストラクター コードでローカル変数を作成すると、実際にはクラス全体にプライベート インスタンス メンバーが作成されることになります。ローカル変数の場合は、プライベート インスタンス メソッドを定義する必要があります。たとえば、constructor() という名前を付けることができます。constructor() のプライベート インスタンス メソッドでは、ローカル変数と実行するコードを元の { で定義します。これで、クラスの最後で直接呼び出すことができます。したがって、より良い書き方は次のようになります:
class2 = function() {
// プライベート フィールド
var m_first = 1;
var m_second = 2; >/ / プライベートメソッド
function method1() {
alert(m_first);
}
var method2 = function() {
alert(m_first);
// パブリックフィールド
this.first = "first";
this.next = ['s','e','c','o','n','d']; >
// パブリック メソッド
this.method1 = method2;
this.method2 = function() {
alert(this.second)}
//コンストラクター
{
method2();
}
}
// パブリック メソッド
class1.prototype.method3 = function() {
var o = new class2();
o.method2(); .method3 ();
alert(o.first);
この例では、class1 の例にいくつかの追加が加えられていることがわかりました。パブリック インスタンス フィールドとパブリック インスタンス メソッドが追加され、これらをパブリック インスタンス メンバーと呼びます。
パブリック インスタンス メンバーの作成は実際には非常に簡単であることがわかりました。1 つの方法は、値が関数以外の型の場合、パブリック インスタンス フィールドです。値が Function type の場合、それはパブリック インスタンス メソッドです。もう 1 つの方法は、className.prototype.memberName に値を割り当てることです。割り当て可能な型は this.memberName と同じです。
このメソッドを使用して定義する必要がありますか?それともプロトタイプメソッドを使用して定義する必要がありますか?
実際、それらにはそれぞれ独自の用途があり、それらの間の関係は、一方が他方より優れているというものではありません。場合によっては、パブリック インスタンス メンバーを特定の 1 つの方法でのみ定義でき、他の方法では定義できない場合があります。その理由は、実際には異なるためです。
1. プロトタイプ メソッドはクラスの外部でのみ定義される必要があります。このメソッドはクラス内でのみ定義できます。
2. クラス内にプロトタイプメソッドが定義されている場合、プライベートインスタンスのメンバーにアクセスする場合は、常に最後のオブジェクトインスタンスのプライベートインスタンスのメンバーにアクセスします。
3. プロトタイプモードで定義されたパブリックインスタンスメンバーは、クラスのプロトタイプ上に作成されたメンバーです。このメソッドで定義されるパブリック インスタンス メンバーは、クラスのインスタンス オブジェクト上に直接作成されるメンバーです。
最初の 2 つの違いに基づいて、パブリック インスタンス メソッドでプライベート インスタンスのメンバーにアクセスしたい場合は、このメソッドを使用して定義する必要があるという結論を導き出すことができます。
3 番目の違いについては、後で継承について説明するときにさらに詳しく分析します。ここで知っておく必要があるのは、この違いだけです。
パブリック インスタンスのメンバーとプライベート インスタンスのメンバーの名前が同じであることもわかります。競合は発生しないでしょうか。
もちろんそうではありません。その理由は、それらのアクセス方法が異なるためです。クラス内でパブリック インスタンスのメンバーにアクセスする場合は、このプレフィックスを使用して参照する必要があります。プライベート インスタンスのメンバーがクラス内でアクセスされる場合、このプレフィックスを使用してアクセスすることはできません。クラスの外部にアクセスする場合、クラスのインスタンス オブジェクトを介してアクセスできるのはパブリック メンバーのみであり、プライベート メンバーにはアクセスできません。
2.3 パブリック静的メンバー
パブリック静的メンバーの定義は非常に簡単です。次に例を示します。
class3 = function() {
// プライベート フィールド
var m_first = 1;
var m_second = 2;
function method1( ) {
alert(m_first);
}
var method2 = function() {
alert(m_first);
// コンストラクター
{
method1 ();
method2();
}
}
// パブリック静的フィールド
// パブリック静的メソッド
class3.method1 = function() {
alert(class3.field1)
}
class3.method1(); >この例の class3 は class1 と同じであり、非常に似ています。違いは、class3 の外側で、class3 の静的フィールドと静的メソッドを定義していることです。
これを定義する方法は、className.memberName に値を直接割り当てることです。
ここで定義された静的フィールドと静的メソッドには、オブジェクトを作成せずに、クラス名参照を通じて直接アクセスできます。したがって、これらはパブリック静的メンバーです。
ただし、覚えておくべきことの 1 つは、パブリック静的メンバーを、それが配置されているクラス内で定義してはいけないということです。そうしないと、予期しない結果が得られます。次の例を見てみましょう:
コードをコピー
var s_second = 2; 🎜>関数メソッド 1 () {
アラート (m_first);
}
var メソッド 2 = function() {
アラート (m_秒);
クラス 4.メソッド 1 = function( ) {
s_second;
}
class4.method2 = function() {
alert(s_second);
}
var o1 = new class4(); 🎜>class4.method2(); // 2
class4.method1();
class4.method2(); ); // 2
class4.method1()
class4.method2();
この例では、s_second がプライベート静的メンバーの役割を果たすことを期待していますが、出力は期待したものではありません。 s_second は実際には、プライベート静的メンバーではなく、class4 のプライベート インスタンス メンバーであることがわかります。 class4 のメソッド 1 およびメソッド 2 によってアクセスされるプライベート メンバーは、常にクラスの最後のインスタンス オブジェクト内のプライベート インスタンス メンバーです。
何が問題ですか?
問題は、new class4() を通じてオブジェクト インスタンスが作成されるたびに、class4 内のすべてのステートメントが再実行されるため、s_second がリセットされ、新しいオブジェクトのプライベート インスタンス メンバーになることです。 Class4.method1 と class4.method2 も再定義されており、この定義により変数のスコープも最後のオブジェクトに切り替わります。これは、プロトタイプを通じて作成されたパブリック インスタンス メソッドがクラス内で定義されている場合に発生するエラーと同じです。
したがって、パブリック静的メンバーが配置されているクラス内でパブリック静的メンバーを定義しないように注意してください。プロトタイプ メソッドを通じて作成されたパブリック インスタンス メソッドをクラス内で定義しないでください。
プライベート静的メンバーを定義するにはどうすればよいですか?
2.4 プライベート静的メンバー
私たちは、関数を使用して関数を作成することによってのみ、プライベート メンバー (静的メンバーであってもインスタンス メンバーであっても) を作成できることを基本概念ですでに理解しました。 )、データ隠蔽の目的を達成するには、新しいスコープを作成する必要があります。以下に採用する方法はこの点に基づくものである。
プライベート静的メンバーの実装は、新しいスコープを作成する匿名関数を作成することによって実現されます。
通常、匿名関数を使用するときは、それを変数に代入し、この変数を通じて匿名関数を参照します。この場合、無名関数を繰り返し呼び出すことも、オブジェクトをクラスとして作成することもできます。ここで、作成した匿名関数は変数に割り当てられず、作成後すぐに実行されます。または、オブジェクトとしてインスタンス化され、オブジェクトは変数に割り当てられません。この場合、関数自体またはそのインスタンスは、関数自体またはそのインスタンスになります。変換されたオブジェクトには再びアクセスできないため、その唯一の機能は、新しいスコープを作成し、その内部のすべてのローカル変数と関数を分離することです。したがって、これらのローカル変数と関数は、必要なプライベート静的メンバーになります。このすぐに実行される匿名関数、またはすぐにインスタンス化される匿名関数を静的カプセル化環境と呼びます。
まず、匿名関数を直接呼び出してプライベート静的メンバーを持つクラスを作成する例を見てみましょう:
class5 = (function() {
// プライベート静的フィールド
var s_first = 1;
var s_second = 2;
// プライベート静的メソッド
function s_method1() {
s_first ;
}
var s_second = 2;
functionconstructor() {
// プライベート フィールド
var m_first = 1;
新しい JavaScript オブジェクト指向トレーニング (2)
var m_second = 2;
// プライベート メソッド
function method1() {
alert( m_first);
}
var method2 = function() {
alert(m_second);
}
// パブリックフィールド
this.first = "first";
this.second = ['s','e','c','o','n','d'];
// パブリック メソッド
this.method1 = function() {
s_second--;
}
this.method2 = function() {
alert(this.second);
/ / コンストラクター
{
s_method1();
this.method1();
}
}
// パブリック静的メソッド
constructor.method1 = function() {
s_first ;
alert(s_first);
constructor.method2 = function() {
alert
}
return コンストラクター; )();
var o1 = 新しいクラス 5.method1();
o1.method2(); = new class5();
class5.method2();
(function(); 🎜>...
関数コンストラクター () {
...
}
戻りコンストラクター
静的カプセル化環境を作成するには、実際のクラスがこの環境で定義され、最後に、return ステートメントを通じて最終クラスがグローバル変数 class5 に返され、その後、class5 A クラスを通じてこのバンドを参照できます。静的プライベートメンバーを使用します。
プライベート静的メンバーとプライベート インスタンス メンバーを区別するために、プライベート静的メンバーの前に s_ 接頭辞を使用し、プライベート インスタンス メンバーの前に m_ 接頭辞を使用します。これにより、名前の重複が回避されるため、プライベート オブジェクトは常に使用できます。静的メンバーでアクセスできます。
ただし、この命名方法は必須ではなく、推奨されるだけです。名前が重複している場合、プライベート静的メンバーは、クラス コンストラクターとインスタンス メソッドでアクセスできます。これはプライベート インスタンス メンバーであり、静的メソッド (パブリック静的メソッドでもプライベート静的メソッドでも) でアクセスされるものはすべてプライベート静的メンバーです。
クラス外および静的カプセル化環境でプロトタイプを通じて定義されたパブリック インスタンス メソッドは、プライベート静的メンバーにアクセスします。
静的カプセル化環境の外部で定義されたパブリック静的メソッドおよびプロトタイプを通じて定義されたパブリック インスタンス メソッドは、プライベート静的メンバーに直接アクセスできません。
匿名関数を直接インスタンス化してプライベート静的メンバーを持つクラスを作成する別の方法は、上記の例とよく似ています:
new function() {
// プライベート静的フィールド
var s_first = 1;
var s_second = 2; 🎜>// プライベート静的メソッド
function s_method1() {
s_first ;
}
var s_second = 2;
class6 = function() {
// プライベートフィールド
var m_first = 1;
var m_second = 2;
// プライベートメソッド
function method1() {
alert(m_first)
var method2 = function() {
alert(m_second);
}
// パブリックフィールド
this.first = "first";
this.second = ['s ','e','c','o','n','d'];
// パブリック メソッド
this.method1 = function() {
s_second-- ;
}
this.method2 = function() {
alert(this.second);
// コンストラクター
{
s_method1 ();
this.method1();
}
}
// パブリック静的メソッド
class6.method1 = function() {
s_first; );
}
class6.method2 = function() {
alert(s_second)
}
}; >クラス6.メソッド1();
クラス6.メソッド2();
クラス6.メソッド1();
o2.method2();
この例の結果は、最初のメソッドで作成した例と同じです。ただその静的カプセル化環境は次のようになっています:
new function() {
...
};
ここでは、関数には戻り値がなく、class5 の定義が直接含まれています。静的カプセル化環境は、var で定義されていない変数に値を割り当てることによって内部的に実装されます。
もちろん、関数の戻り値を定義せずに
(function() {
...
})();
を使用することもできます。 var で定義されていない変数に値を代入することで、プライベート静的メンバーを持つクラスの定義を実装します。
ここでは 2 つのメソッドは同等です。
2.5 静的クラス
いわゆる静的クラスは、インスタンス化できず、静的メンバーのみを含むクラスです。
JavaScript では、匿名関数オブジェクトを直接インスタンス化することで静的クラスを実装できます。例:
コードをコピー
コードは次のとおりです:
class7 = new function() {
// プライベート静的フィールド
method1();
alert(s_second);
}
}
class7。
class7 は実際にはオブジェクトですが、このオブジェクトは匿名クラスに属していることがわかります。class7 オブジェクトが作成された後は、このクラスは使用できなくなります。 Class7 は関数ではないため、クラスとしてインスタンス化できません。したがって、ここでは静的クラスに相当します。