0

私は次のパターンが好きになりました(この場合、Coffeescriptの方が読みやすくなります):

Parent = (proto)->
  self = Object.create proto
  public1 = ->
    console.log "in public1 with self: ", self
    console.log "in public1 with name: ", self.name

  self.public1 = public1
  self

Child = (proto)->
  self = new Parent proto

  private1 = ->
    console.log "in private1 with self: ", self
    console.log "in private1 with name: ", self.name
    self.public1()

  public2 = ->
    console.log "in public2 with self: ", self
    console.log "in public2 with name: ", self.name
    private1()

  self.public2 = public2
  self

GrandChild = (proto)->
  self = new Child proto

  public3 = ->
    console.log "in public3 with self", self
    console.log "in public3 with name: ", self.name
    self.public2()

  self.public3 = public3
  self

felix = new GrandChild name: "Felix"
felix.public2()

多重継承のその素朴な試みは機能し、「自己」の単純で明らかに便利な使用を可能にします...あなたが私のように他のoop言語から来ているときは賢いです。

落とし穴:すべてのGrandChildオブジェクトは、新しい親オブジェクトだけでなく新しい子オブジェクトも作成するため、多くのGrandChildオブジェクトが作成された場合にメモリ消費量が増加します。

GrandChildのプロトタイプをChildとParentのメソッドで拡張すると、私が理解している限り(そして多くのスペースを節約して)、GrandChildオブジェクト内のメソッドを参照するだけですが、上下に読んでも、自分のやり方で自分自身にアクセスする方法が見つかりません。上のソリューションで。

Coffeescript自体が、JSのプロトタイプの継承に加えてクラスベースの継承システムを提供していることを私は知っています。他のライブラリも同様にソリューションを提供します。ユースケースに応じて適切なソリューションを選択するために何が起こっているのかを簡単に理解したいと思います。

たとえば、Childのprivate1とpublic2をプロトタイプに入れて、これらの関数がコピーされるのではなく参照されるようにするにはどうすればよいでしょうか。

その時点で誰かが私を教えてもらえますか?

4

1 に答える 1

1

落とし穴:すべてのGrandChildオブジェクトは、新しい親オブジェクトだけでなく新しい子オブジェクトも作成するため、多くのGrandChildオブジェクトが作成された場合にメモリ消費量が増加します。

誤り。ここで行っていることは、たとえば、new GrandChildをインスタンス化してから、コンストラクターからのメソッドで、次にコンストラクターからParentのメソッドでそれを装飾することです。それは孫までずっと同じオブジェクトです。その点で、ダミーオブジェクトでコンテキストを散らかすことはまったくありません。ChildGrandChildObject.create proto

GrandChildのプロトタイプをChildとParentのメソッドで拡張すると、私が理解している限り(そして多くのスペースを節約して)、GrandChildオブジェクト内のメソッドを参照するだけですが、上下に読んでも、自分のやり方で自分自身にアクセスする方法が見つかりません。上のソリューションで。

クロージャベースのプライベートメソッドとプロトタイプは、通常はうまくいきません。このようなコンストラクターですべてを実行すると、柔軟性が大幅に向上しますが、プロトタイプを使用する利点が失われます(新しいスコープで関数を常に再定義しないことによる速度など)。

Coffeescript自体が、JSのプロトタイプの継承に加えてクラスベースの継承システムを提供していることを私は知っています。他のライブラリも同様にソリューションを提供します。ユースケースに応じて適切なソリューションを選択するために何が起こっているのかを簡単に理解したいと思います。

そうです、そしてコーヒースクリプトを使うときそれを使わない理由はありません。多くの考えがそれに注がれています。ただし、プライベートメソッドには注意が必要です。通常、プライベートメソッドは単純にパブリックになりますが、プライベートであるFoo.prototype._privateMethodことを示すためにアンダースコアがプレフィックスとして付けられます。それが十分でない場合、物事はファンキーになり始めます。

たとえば、Childのprivate1とpublic2をプロトタイプに入れて、これらの関数がコピーされるのではなく参照されるようにするにはどうすればよいでしょうか。

パブリックメソッドはプロトタイプに組み込まれ、プライベートではなく、うまく伝播できます。プライベートは、他の言語のようにサポートされていないため、JavaScriptで物事を考えるのに実際には良い方法ではありません。代わりに、アクセスできる値(関数を含む)は、ローカル変数またはクロージャを介して現在のスコープにあるか、ローカル変数またはクロージャを介して現在のスコープにあるオブジェクトのプロパティです。


編集:

最後に、ここにあるパターンは、キーワードなしでより適切に提供されます。new任意のオブジェクトを作成して返すため、オブジェクトを作成するためにJSエンジンは必要ありません。newしたがって、ここでコードから完全に削除すれば、コードは機能するはずです。

コンストラクター関数には癖があります。オブジェクトを返すときは、を介して作成されたオブジェクトではなく、そのオブジェクトを返しますnewselfここでは、を介して自分で作成したものを返しますObject.create。コンストラクター関数が非オブジェクト(文字列、数値、関数、null)を返す場合、実際にはthis代わりに返されます。Coffee Scriptでは、関数が暗黙的に返されるため、これは注意が必要な場合があります。また、coffeescriptクラスを使用する場合、コンストラクターは何も返さないため、この奇妙な問題に対処できます。

于 2012-05-07T22:34:19.893 に答える