9

私はEcmaScript5仕様でObject.createをいじっており、多重継承型の構造を作成しようとしています。

a、b、cといういくつかの関数があるとします。プロトタイプを扱うだけで、私はこれを行うことができます:

function a () {}
a.prototype = {
    fnA = function () {},
    propA = 500
};

function b () {}
b.prototype = a.prototype;
b.prototype.fnB = function () {};
b.prototype.propB = 300;

function c () {}
c.prototype = b.prototype;
c.prototype.fnC = function () {};
c.prototype.propC = 200;

しかし、Object.createを使用して、私はこれを行うでしょう:

function a() {}
a.prototype = {
    fnA = function () {},
    propA = 500
};

var b = Object.create(new a());
b.fnB = function () {};
b.propB = 300;

var c = Object.create(b);
c.fnC = function () {};
c.propC = 200;

どちらの方法でも同じ結果が得られると思います。

コンストラクター関数の代わりにオブジェクトに戻るので、これはちょっと不格好なようです。通常のプロトタイプの継承を行うことは、煩わしさが少なく、動作するために特別な処理を必要としないモジュラーアプリケーションにとってより理にかなっているように思われます。

私は何かが足りないのですか?コンストラクターを作成してObject.createを作成しようとする利点はありますか?または、これは既存のオブジェクトをコピーする場合にのみ役立ちますか?プロトタイプにアタッチされたプロパティと関数にのみアクセスしたいので、後でオブジェクトに追加された関数とプロパティにはアクセスしません。

または、これはどうですか(またはより良いディープコピーを使用しますが、考え方は同じです)?

function A () {}
A.prototype = {
    fn: function () {
        console.log(this.propA + 30);
    },
    propA: 20
};

function B () {}
Object.keys(A.prototype).forEach(function (item) {
    B.prototype[item] = A.prototype[item];
});
B.prototype.propA = 40;

function C () {}
Object.keys(B.prototype).forEach(function (item) {
    C.prototype[item] = B.prototype[item];
});
C.prototype.fn = function () {
    console.log(this.propA + 3);
};


var a = new A(),
    b = new B(),
    c = new C();

a.fn();
b.fn();
c.fn();
4

2 に答える 2

4

実際には、両方の方法で同じ結果が得られるわけではありません。次の行を検討してください。

b.prototype = a.prototype;

これが行っていることはb.prototype、 とまったく同じオブジェクト参照に設定することa.prototypeです。最初のオブジェクトを (たとえばfnBメソッドを追加して) 変更すると、2 番目のオブジェクトも変更されます。それらは同じものです。最初のコード セットの最後には、同じメソッドとプロパティを持つまったく同じ 3 つのプロトタイプが作成されます。

プロトタイプの継承の全体的なポイントは、「興味深い」オブジェクト (つまり、必要なすべての動作を備えたもの) を定義し、それを Object.create で複製し、ニーズに合わせて複製を変更することです (通常、オブジェクトのプロパティを変更するのではなく、その方法)。

adder オブジェクトがあるとします。

var adder = {x: 0, y: 0};
adder.execute = function () {
  return this.x + this.y;
}

次に、クローンを作成し、そのプロパティを設定します。

var myadder = Object.create(adder);
myadder.x = 1;
myadder.y = 2;
console.log(myadder.execute()); // 3

明らかにこれはばかげた例ですが、コンストラクターとそれらのコンストラクターに明示的なプロトタイプを記述する必要なく、プロトタイプの継承を考えることができることを示しています。

于 2011-06-14T02:35:02.237 に答える