13

プロトタイプを使用するメソッドとプロトタイプを使用しないメソッドのオーバーライドの違いは何ですか。検討:

例 1:

function Animal() {
    this.sleep = function () {
        alert("animal sleeping");
    };

    this.eat = function () {
        alert("animal eating");
    };
}

function Dog() {
    this.eat = function () {
        alert("Dog eating");
    };
}

Dog.prototype = new Animal;

var dog = new Dog;

dog.eat();

例 2:

function Animal() { }

function Dog() { }

Animal.prototype.sleep = function () {
    alert("animal sleeping");
};

Animal.prototype.eat = function () {
    alert("animal eating");
};

Dog.prototype = new Animal;

Dog.prototype.eat = function () {
    alert("Dog eating");
};

var dog = new Dog;

dog.eat();

Dogどちらの例も、クラスがクラスの eat メソッドをオーバーライドしているのと同じ効果を生み出すと思いますAnimal。それとも、何か違うことが起こっていますか?

4

4 に答える 4

11

最初のメソッドでは、各インスタンスがメソッドとメソッドAnimalの独自の実装を取得します。sleepeat

sleep2 番目のモデルでは、すべてのインスタンスがおよびeatメソッドの同じインスタンスを共有します。

メソッドを共有できるので、2 番目のモデルの方が優れています。

于 2013-03-19T10:49:10.187 に答える
10

Arun が最初の例で述べたように、新しいインスタンスごとsleepに関数を作成しています。eat2 番目の例では、すべてのインスタンス間で共有される関数は 1 つだけsleepですeat

この場合、2 番目の方法の方が適していますが、最初の方法を使用する場合と 2 番目の方法を使用する場合を知っておくとよいでしょう。最初に少し理論を説明します。

注:private JavaScriptには、 、publicsharedおよびの 4 種類の変数がありますstatic

プライベート変数は、それらが定義されている関数の外ではアクセスできません。例えば:

function f() {
    var x; // this is a private variable
}

パブリック変数はthis、関数内のオブジェクトで定義されます。例えば:

function f() {
    this.x; // this is a public variable
}

共有変数はprototype関数上で共有されます。例えば:

function f() {}

f.prototype.x; // this is a shared variable

静的変数は、関数自体のプロパティです。例えば:

function f() {}

f.x; // this is a static variable

ほとんどの場合、コンストラクター関数のメソッドを共有メソッドとして宣言するのが最善です。これは、コンストラクターのすべてのインスタンスがそれらを共有するためです。ただし、メソッドがプライベート変数にアクセスする必要がある場合は、それ自体をパブリック メソッドとして宣言する必要があります。

注:これは私の独自の命名法です。多くの JavaScript プログラマーはそれを順守しません。その他は Douglas Crockford の命名法に従っているようです: http://javascript.crockford.com/private.html

JavaScript でのプロトタイプの継承について詳しく知るには、次の回答をお読みください: https://stackoverflow.com/a/8096017/783743

于 2013-03-19T11:03:36.837 に答える
0

最初の例では、新しいDogインスタンスごとに独自のeatメソッドがあり、2番目の例では、にeatメソッドが1つだけあり、これは、前述のArunDog.prototypeのような将来のすべてのインスタンス間で共有されます。Dog

これは、これら2つの間の唯一の「トリッキーな」違いです。ただし、prototype高いメモリ消費とリークを回避するために、でメソッドを定義することをお勧めします。

于 2013-03-19T11:05:17.627 に答える
0

最初の例のメソッドは、オブジェクト インスタンスで定義されています。

Dogプロトタイプを新しいAnimalインスタンスに設定しているため、から関数Dogを継承sleepします。次に、コンストラクターでインスタンスメソッドとしてDEFINING (NOT OVERRIDING )メソッドを使用すると、インスタンスで継承されたメソッドが表示になります。eatAnimaleatDogeatDog

次の例を検討してください。

function LittleDog() { }
LittleDog.prototype = Object.create(Dog.prototype);
(new LittleDog()).eat();

上記のanimal eatingコードは、最初の例のコードで警告します。

Dog eatingそして、2番目のコードで警告します。

于 2013-03-19T11:18:47.987 に答える