5

Dogクラスからのプロトタイプ継承を介して継承する新しいクラスを作成しようとしていますAnimal:

function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  this.name = "dog";
  this.prototype = new Animal();
}

new Dog().writeName()

JS フィドル

ただし、Javascript エラーが発生します: Uncaught TypeError: Object #<Dog> has no method 'say'.

なんで?オブジェクトはオブジェクトをプロトタイプとしてDog保持するべきではありませんか?Animal

4

3 に答える 3

7
function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  this.name = "dog";

}
Dog.prototype = new Animal();
dog = new Dog();
dog.writeName();

現在、犬は動物のすべての特性を持っています。

jsfiddle

于 2012-06-30T01:29:49.760 に答える
3

もちろん、@ryanの答えは正しいですが、彼はそれについて何が違うのかを実際には言っておらず、初心者には明確ではないかもしれません.

あなたが犯している間違いは、インスタンスを現在のインスタンスで名前が付けられたプロパティにthis.prototype = new Animal();割り当てることです(によって参照されます)が、このコンテキストで名前が付けられたプロパティについて特別なことは何もありません。AnimalprototypeDog thisprototype

プロパティは、関数オブジェクトprototypeでのみ魔法です。その新しいオブジェクトの internal/hidden [[prototype]]ポインタを使用しての新しいインスタンスを作成すると、 が指すオブジェクトが参照されます。名前は、他のコンテキストでは特別ではありません。SomeFuncnew SomeFunc()SomeFunc.prototypeprototype

于 2012-06-30T02:43:03.323 に答える
2

「プロトタイプ」プロパティは単なる通常のプロパティです。委任を処理する実際の [[Proto]] プロパティは隠され、オブジェクトの作成後に直接操作することはできません (一部の拡張機能を除く: Firefox では、その__proto__プロパティ)。

あなたがやっていることと精神的に似ている正しい Javascript 継承の例は、正しい [[Prototype]] プロパティを持つ犬を作成するために Object.create を使用します:

function Animal() {
  this.name = "animal";
  this.writeName = function() {
    document.write(this.name);
  }    
}

function Dog() {
  var dog = Object.create(new Animal())
  dog.name = "dog";
  return dog;
}

(new Dog()).writeName()

より慣用的な例は、ライアンの答えのようなものですが、犬のプロトタイプをインスタンス化するObject.create代わりに使用することをお勧めしnew Animalます。動物のメソッドは、コンストラクターに手動でアタッチするのではなく、別の動物のプロトタイプに配置します。

于 2012-06-30T01:29:05.850 に答える