10

私はクラスのオブジェクト指向言語から来ており、最近、それらの高度な動的言語 (JavaScript、Python、および Lua) を学習しています。これらの言語で OO を使用する方法についてのヒントが必要です。このようなアプローチの落とし穴と欠点、および従来の OO と比較した利点を知っておくと役立ちます。

私が得た一般的な概念は、プロトタイプベースの OO は基本的にオブジェクトを使用してプログラミングすることですが、通常の OO ではオブジェクトを作成および使用するための固定された定義済みの方法があるのに対し、それらの使用方法に関する標準はありません。

要約すると、そのようなアプローチの良い部分、悪い部分、醜い部分は何ですか?

4

5 に答える 5

13

プロトタイプベースの OO は、静的な型チェックにはあまり向いていません。プロトタイプベースの OOには、新しいオブジェクトを作成する標準的な方法があり、既存のオブジェクトを複製して変更します。工場などを建設することもできます。

人々が最も気に入っている (「良い」) ことは、プロトタイプベースの OO が非常に軽量で柔軟性があり、非常に高い出力対重量比を提供することだと思います。

プロトタイプベースの OO の使用方法に関するヒントについては、 The Power of Simplicityに関するオリジナルの Self ペーパーから始めるのが最適です。

于 2008-12-22T04:34:49.813 に答える
7

ここで帯域幅を節約するには、「JavaScript で「クラス」をエミュレートするにはどうすればよいですか? (サードパーティ ライブラリの有無にかかわらず)」に関する私の回答へのリンクです。これには、追加の参照と例が含まれています。

簡単に言えば、JavaScript のプロトタイプOOの核心は委譲です。このスタイルの OOP では、同じ「クラス」のさまざまなオブジェクトが、メソッドとプロパティの処理を同じプロトタイプ (通常は 3 番目のオブジェクト) に委譲できます。

var foo = {
    property: 42,
    inc: function(){
        ++this.counter;
    },
    dec: function(){
        --this.counter;
    }
};
// Note: foo does not define `counter`.

プロトタイプとして foo を持つオブジェクトのコンストラクターを作成しましょう。事実上、処理されないものはすべて foo に委譲されます。

var Bar = function(){
    this.counter = 0;
};
Bar.prototype = foo;  // This is how we set up the delegation.

// Some people refer to Bar (a constructor function) as "class".

var bar = new Bar();

console.log(bar.counter);  // 0 --- Comes from bar itself
console.log(bar.property); // 42 --- Not defined in bar, comes from foo

bar.inc();  // Not defined in bar => delegated to foo
bar.inc();
bar.dec();  // Not defined in bar => delegated to foo
// Note: foo.inc() and foo.dec() are called but this === bar
// that is why bar is modified, not foo.

console.log(bar.counter);  // 1 --- Comes from bar itself

inc()バー上で直接定義しましょう:

bar.inc = function(){
    this.counter = 42;
};

bar.inc();  // Defined in bar => calling it directly.
            // foo.inc() is not even called.
console.log(bar.counter);  // 42 --- Comes from bar

単一継承チェーンの設定:

var Baz = function(){
    this.counter = 99;
};
Baz.protype = new Bar();

var baz = new Baz();

console.log(baz.counter); // 99
baz.inc();
console.log(baz.counter); // 100

console.log(baz instanceof Baz);    // true
console.log(baz instanceof Bar);    // true
console.log(baz instanceof Object); // true

いいですね。

于 2008-12-22T03:15:34.387 に答える
2

JavaScript でクラスベースの継承をエミュレートする方法について心配する前に、JavaScript でのプロトタイプの継承を簡単に読んでください。

于 2009-01-03T00:50:41.713 に答える
1

古典的な継承は、柔軟性の点で本質的に欠陥があり、「このオブジェクトはこのタイプであり、他にはありません」と言っています。一部の言語では、これを軽減するために多重継承が導入されていますが、多重継承には独自の落とし穴があるため、継承 (静的に型付けされた言語では、コンパイル時のメカニズムではなく実行時) に対する純粋な構成の利点が明らかになります。

構成の概念をこの「純粋な」レベルに引き上げると、静的型付けとともに古典的な継承を完全に排除できます。実行時にオブジェクトを構成し、それらを青写真として使用する (プロトタイプのアプローチ) ことで、継承によってオブジェクトを厳密にボックス化することを心配する必要がなくなり、多重継承アプローチに固有の問題に負担をかけることもありません。

したがって、プロトタイプとは、モジュールのより柔軟な開発を意味します。

もちろん、静的型付けなしで開発するのが簡単であると言うのはまったく別のことです。IMO、そうではありません。

于 2010-10-18T10:31:26.690 に答える
0

まず第一に、プロトタイプ モデルは実際にはそれほど違いはありません。Smalltalk も同様の方式を使用します。クラスはクラスのメソッドを持つオブジェクトです。

クラスの視点から見ると、クラスは実際には、同じデータとすべて同じメソッドを持つオブジェクトの等価クラスです。メソッドをプロトタイプに追加することは、新しいサブクラスを作成することと見なすことができます。

実装は簡単ですが、効果的な型チェックを行うのは非常に困難です。

于 2008-12-22T02:31:15.880 に答える