3

私はJSプロトタイプについて学んでいます。

他のコンストラクター (B) のインスタンスからコンストラクター (A) のプロトタイプを設定した場合、その (B の) インスタンスは A に共有プロパティを導入しますか?

例 1

function A(){ 
    var private = '';

    this.getPrivate = function(){ 
        return private
    }; 

    this.setPrivate = function(_private){ 
        private = _private; 
    }; 
}

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // Here `private` is behaving as singleton property. Why?

例 2

function A(){ 
    var private = '';
}

A.prototype.getPrivate = function(){ 
    return this.private
}; 

A.prototype.setPrivate = function(_private){ 
    this.private = _private; 
}; 

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // This time private is not singleton property.

遊んでいるうちに、プロトタイプのこの新しい側面を発見しました。

  • 例 1 では、privateプロパティが異なるインスタンス間で共有されるのはなぜBですか?
  • 例 2 では、privateプロパティが両方のインスタンスで独立して存在するのはなぜですか? ただし、元のプロパティは変更されていませんが、ゲッター/セッターはプロトタイプを介して定義されています。
  • 例 1 は、シングルトン プロパティの実装と見なすことができますか?
  • インスタンスによるプロトタイピングとプロトタイプによるプロトタイピング、違いは何ですか? 例えば
    B.prototype = new A();
    B.prototype = (new A()).constructor.prototype
  • プロトタイピングの完全な秘密は何ですか?
4

4 に答える 4

1

例1では、クロージャスコープを使用してプライベートを参照しています。Aは一度だけインスタンス化されるため、その1つのインスタンスが定義されます。

例2では、​​this.privateは関数Aのprivateのインスタンスを参照していません。実際、「this」という単語を使用しているため、オブジェクトの「this」を参照しています。したがって、this.privateは、関数に応じてb1.privateまたはb2.privateのいずれかを意味します。例2では、​​関数Aで定義されたプライベートがクロージャースコープに失われ、定義されていないかのようになります。

于 2012-06-26T19:52:56.940 に答える
1

例 1 で、B の異なるインスタンス間でプライベート プロパティが共有されるのはなぜですか?

はい、彼らがやります

例 2 で、プライベート プロパティが両方のインスタンスで独立して存在するのはなぜですか? ただし、元のプロパティは変更されていませんが、ゲッター/セッターはプロトタイプを介して定義されています。

各インスタンスは他のインスタンスから独立しているためです。それが望ましくない場合は、オブジェクト リテラル表記を使用してクラスを作成します。

例 1 は、シングルトン プロパティの実装と見なすことができますか?

いいえ、シングルトンは常に同じオブジェクト インスタンスを返すためです。これは、各インスタンスが独立しているという 2 番目の質問に関連しています。最初の例から、そのクラスの多くのインスタンスを作成できます。シングルトンを作成するには、グループ化演算子を使用した自己呼び出し関数を使用するシングルトンまたはモジュールパターンが存在します(例: のラッピング関数) 。()

インスタンスによるプロトタイピングとプロトタイプによるプロトタイピング、違いは何ですか? 例えば

を使用constructorすると、子クラスのコンストラクターと親クラスの間に混乱がないことを確認できます。親クラスを拡張するときと同じ概念です。子クラスでは、子クラスのコンストラクター関数で親クラスを構築します。

プロトタイピングの完全な秘密は何ですか?

さまざまな JS Ninja ブログの優れた記事を調べます。私は愛してる:

ここに良い記事があります:

于 2012-06-26T19:38:01.397 に答える
1

プロトタイピングの秘訣 (これがすべてを説明しています) は、 のすべてのインスタンスがB同じプロトタイプを共有することです。つまり、プロトタイプの新しいインスタンスにコピーされませんBの任意のインスタンスのプロトタイプ関数をB起動すると、実際には常に同じ関数が実行されます。そのため、「プライベート」変数がコピーされます (実際にはコピーされません。常に同じ変数を参照しているだけです)。「非プライベート」変数は、キーワードthisが関数の現在の「ホルダー」を参照することを除いて、同じように動作します。そのため、prototype を呼び出すとthis、prototype メソッドが実際にはオブジェクトのメソッドであるという錯覚が生じます。そうではない。

インスタンスを介したプロトタイピングは悪い習慣と見なされます。これは、インスタンスが呼び出されるタイミングとプロトタイピングのタイミングに応じて、インスタンスのプロパティが増減する可能性があるためです。プロトタイプは、ほとんどの場合、リテラル オブジェクトの作成または他のオブジェクトのプロトタイプの拡張によって定義されます。

最後に: ある意味では、プロトタイピングはシングルトンとして解釈される可能性があります。

于 2012-06-26T19:29:06.907 に答える
1
  1. 特定のクロージャーにロックダウンされた特定のインスタンスを継承しているためです。データは、オブジェクトではなくクロージャーによって所有されます。オブジェクトの変数とプロパティには大きな違いがあります。

  2. はここvar privateではまったく使用されません。setPrivate()その時点でプロパティが作成されます。

  3. いいえ、クロージャとオブジェクト モデルの間の誤解による偶然です。単純なオブジェクト リテラルを使用することで、より意図的で明確な方法で同じことを行うことができます。

  4. 違いは、最初のオブジェクトでは新しいオブジェクトを取得することですが、2 番目のオブジェクトでA.prototype === B.prototypeは同じオブジェクトを参照するため、一方を変更すると他方も変更されます。

  5. オブジェクトは他のオブジェクトから継承します

ここに良いリソースがあります https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model

于 2012-06-26T19:32:29.320 に答える