0

プロトタイプの継承についての私の理解は、すべてのオブジェクトがプロトタイプ プロパティを持っているということです。プロパティがオブジェクトに存在しない場合は、そのプロトタイプ オブジェクトがチェックされ、チェーンの上流に続きます。

この例では、私のプロトタイプ オブジェクトはカウンター プロパティを持つ単純なオブジェクトです。

すべてのインスタンスが同じプロトタイプを共有することを期待していますが、新しいインスタンスを取得しているようです。このコードの出力は 00 です。01 を期待していました。

明らかな何かが欠けていますか?

"use strict";

var ConstructorFunction = function () {};

ConstructorFunction.prototype = {
    counter: 0,
    count: function () {
        return this.counter++;
    }
};

var a = new ConstructorFunction();
var b = new ConstructorFunction();

$("#output").append(a.count());
$("#output").append(b.count());

これがjsfiddleです:http://jsfiddle.net/hdA6G/5/

4

5 に答える 5

4

プロトタイプ プロパティがすべてのインスタンスで共有されていることは事実です。問題は、prototype プロパティを決して変更しないことです。いくつかの追加のログを使用してフィドルを見てください。

"use strict";

var ConstructorFunction = function () {};

ConstructorFunction.prototype = {
    counter: 0,
    count: function () {
        return ++this.counter;
    }
};

var a = new ConstructorFunction();
var b = new ConstructorFunction();

$("#output").append(a.hasOwnProperty("counter") + " "); //false
a.count();
$("#output").append(a.hasOwnProperty("counter") + " "); //true

ご覧のとおり、 を呼び出すとすぐに、++this.counterそれ以降使用されるローカル プロパティが作成されます。

私はこれが起こると仮定します:

++this.counterと解釈されthis.counter = this.counter + 1ます。まず、等号の右の部分が評価され、インスタンスにはcounterプロパティがないため、プロトタイプのカウンター プロパティが使用されます。このプロパティの値は 1 に追加され、次に に割り当てられます。this.counterこれにより、 のような、まったく存在しないプロパティを割り当てる場合と同じ方法で、ローカル プロパティが作成されますa.xy = 1xyその場合、インスタンスのローカル プロパティになります。

編集

プロトタイプ プロパティを引き続き使用できる 2 つの回避策があります。

count1)メソッド内でプロトタイプ プロパティを明示的に設定します。

ConstructorFunction.prototype.count = function() {
    return ++this.constructor.prototype.counter;
};

2) count メソッドを呼び出し、applyプロトタイプをコンテキストとして使用します。

a.count.apply(a.constructor.prototype);

しかし、あなたが行った方法でプロパティを設定するprototypeと、これらの方法の両方で問題が発生します。

 ConstructorFunction.prototype = {
     //...
 };

これは完全なプロトタイプ オブジェクトをオーバーライドするため、そのコンストラクタ プロパティもオーバーライドされます。コンストラクタ プロパティは、プロトタイプ チェーン内の次の上位オブジェクトであるオブジェクトを指すようになりObjectます。これを修正するには、プロトタイプ オブジェクトを割り当てた後にコンストラクターを手動で設定します。

ConstructorFunction.prototype.constructor = ConstructorFunction;

または、プロトタイプ オブジェクトのすべてのプロパティを個別に割り当てます。

ConstructorFunction.prototype.counter = 0;
ConstructorFunction.prototype.count = function () {
    return ++this.counter;
};
于 2013-06-04T07:13:51.460 に答える