7

次のようなコードがたくさんあります。

function Base() {}
function Sub() {}
Sub.prototype = new Base();

ただし、次の場合:

s = new Sub();
print(s.constructor == Sub);

これは誤りです。s のコンストラクターは確かに Sub. これを行うのは従来の/より良いですか?

function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sub.prototype.constructor = Sub;

またはそれは本当に問題ではありませんか?

4

3 に答える 3

9

「コンストラクター」は、それがしているように見えることをしません。これは、その非標準性に加えて、使用を避ける正当な理由です - instanceof とプロトタイプに固執してください。

技術的には、「コンストラクター」は「s」インスタンスのプロパティではなく、透けて見える「サブ」プロトタイプ オブジェクトのプロパティです。Mozilla で「Sub」関数を作成すると、礼儀として Sub 関数を指す「コンストラクタ」を持つ、新しく作成されたデフォルトの Sub.prototype オブジェクトが得られます。

ただし、そのプロトタイプを new Base() に置き換えます。Sub へのリンクを含む元のデフォルト プロトタイプは失われます。代わりに、Sub.prototype は Base のインスタンスであり、「コンストラクター」プロパティをオーバーライドすることはありません。そう:

new Sub().constructor===
Sub.prototype.constructor===
new Base().constructor===
Base.prototype.constructor===
Base

...プロトタイプが変更されていない最も基本的なオブジェクトに至るまで。

これを行うのは従来の/より良いですか?

JavaScript のオブジェクト/クラスを扱う場合、規則は 1 つではありません。すべてのライブラリのメタクラス システムの動作はわずかに異なります。「コンストラクター」を各派生クラスに手動で書き込むものは見たことがありませんが、実際のコンストラクターを本当に利用できるようにしたい場合は、他の方法と同じくらい良い解決策のようです。また、「コンストラクター」を提供しないブラウザー/エンジンと互換性のあるコードを作成します。

ただし、既存の動作の異なる「コンストラクター」プロパティとの混同を避けるために、別の名前を付けることを検討します。

于 2008-12-31T12:47:51.683 に答える
3

オブジェクトが正確に Sub のインスタンスであるかどうかをテストする場合は、instanceof演算子を使用します:-

print(s instanceof Sub);

オブジェクトが Sub のインスタンスなのか、Sub のサブクラスのインスタンスなのかを知りたい場合は、次のisPrototypeOfメソッドを使用します。

print(Sub.prototype.isPrototypeOf(s));
于 2008-12-31T11:18:34.140 に答える
1

うん、

Sub.prototype.constructor = Sub;

instanceof を使用してみましょうが、より良い解決策があります。ここを見てください: GitHub の TDD JS Inheritance で、寄生的な組み合わせの継承パターンを見つけてください。コードはTDD化されているため、非常に迅速に理解し、名前を変更するだけで作業を開始できます。これは、基本的に YAHOO.lang.extend が使用するものです (出典: yahoo の従業員で著者の Nicholas Zakas の Professional JavaScript for Web Developer's、第 2 ED、181 ページ)。ちなみに良書です(一切関係ありません!)

なんで?作業している古典的なパターンには静的な参照変数があるため (ベース オブジェクトで var arr = [1,2] を作成すると、すべてのインスタンスが読み取り/書き込みを持ち、「arr」の「状態を共有」します!これを回避するには、コンストラクター スティーリングを使用します。私の例を参照してください。

于 2009-10-29T15:06:28.720 に答える