3

Javascript で継承を実装するには、一般的に次の 2 つの手順を実行します。

基本クラス「動物」があるとします

var Animal = function(name){
this.name = name;
}

私は今、サブクラス「犬」を同じものから派生させたいと思っています。だから私は言うだろう

var Dog = function(name) {
   Animal.call(this,name);
}

したがって、派生クラスのコンストラクターから親クラスのコンストラクターを呼び出しています。2 番目のステップは、次のようにプロトタイプを設定することです。

Dog.prototype = new Animal();

これで、派生クラス Dog 内から基本の「Animal」クラス プロパティにアクセスできるようになりました。

だから私の質問は、なぜこれらの2つのステップが必要なのですか? を使用して基本クラスのコンストラクターを呼び出すだけの場合

Animal.call(this,name);

Inheritance を実装するにはそれで十分ではありませんか?

を使用してプロトタイプ プロパティ設定する必要があるのはなぜDog.prototype = new Animal();ですか。

上記の2つのステップのそれぞれが何をするのかを理解したかったのですか?

4

6 に答える 6

2
var Animal = function(name){
    this.name = name;
}
Animal.prototype.sleep = function() {
    console.log("Sleeping")
}

... 
// Without this line:
Dog.prototype = new Animal();

// the following code will fail, since `d` does not contain `sleep`
d = new Dog();
d.sleep();

Animal.call(this,name);単に関数を呼び出しますが、呼び出し元の関数Animalと同じものを使用しthisます。

Dog.prototype = new Animal();プロトタイプのプロトタイプを設定します。ただし、Dog.prototype = Object.create(Animal.prototype)より正確な場合があります。

于 2013-03-07T08:01:24.997 に答える
1

コードサンプルは千の言葉に値します:)

var Animal = function(name) {
    this.name = name;
}
Animal.prototype.run = function () {
    // do something
};
var Dog = function(name) {
   Animal.call(this, name);
}

var dog = new Dog('Puppy');
typeof dog.name; // "string"
typeof dog.run; // "undefined"
dog instanceof Animal; // false
dog instanceof Dog; // true

Dog.prototype = new Animal();

var dog = new Dog('Puppy');
typeof dog.name; // "string"
typeof dog.run; // "function"
dog instanceof Animal; // true
dog instanceof Dog; // true

ご覧のとおり、を使用しないとDog.prototype = new Animal();Animal.prototypeメンバーは継承されません。さらに、Dogインスタンスは のインスタンスとは見なされませんAnimal

于 2013-03-07T08:35:39.717 に答える
0

ここでは、のコンストラクター関数を定義しますAnimal

var Animal = function(name){
   this.name = name;
}

次に、コンストラクター関数を定義し、そのDog内部から。のコンストラクター関数を呼び出しAnimalます。super()クラスベースのオブジェクト指向設計と同じように。

var Dog = function(name) {
   Animal.call(this,name);
}

次に、のプロトタイプでDog定義されたメソッドを使用して、のプロトタイプを 作成しAnimalます。ここでは、のメソッドのクローンを作成しませんAnimalが、リンクが設定され、リンクが設定され、それDogAnimal使用して、のメソッドが再使用されます。Animal

Dog.prototype = new Animal();

そして、さらにメソッドを追加して拡張を続けます

Dog.prototype.showName = function(){
     // do something
}
于 2013-03-07T08:12:11.177 に答える
0

2 番目のステップは、プロトタイプ メソッドを継承するのに役立ちます。より複雑なクラスがあると想像してください:

function Animal(name) {
  this.name = name;
}

// shared method
Animal.prototype.say = function () {
  alert( this.name );
};

function Dog() {
  Animal.apply(this, arguments);
}

Dog.prototype = new Animal();


var dog = new Dog('Cooper');
// method has been inherited
dog.say(); // alerts 'Cooper'

ここで試すことができます

于 2013-03-07T08:03:29.343 に答える
0

JavaScript には、クラスもサブクラスもありません。

別の「this」のコンテキストで関数を呼び出して適用します。サンプル コードにあるものは不要です。

//Create your constructor function:
var Animal = function(){}

Animal.prototype = {
    sleep: function(){
         console.log('zzz');   
    },
    bark: function(name){
         console.log(name +' barks!');   
    }
}

var dog = new Animal();

dog.sleep();
dog.bark('asdasd');
于 2013-03-07T08:07:49.870 に答える
0

最初に理解しておくべきことは、JavaScript には古典的な継承がないことです。これは、Java や C# などの C 言語で知られているメカニズムです。JavaScript では、prototypal-inheritance を使用してコードを再利用できます。私たちが持っている唯一のものはオブジェクト、つまり生きていてインスタンス化する必要のないコードのブロックです。例: オブジェクトで関数が呼び出されると (メソッドのように)、現在のオブジェクトは関数が既知であるかどうかが検査されます。見つからない場合、エンジンはそれをプロトタイプ (別のオブジェクト) と呼び、関数名が既知であり、呼び出すことができるかどうかを検査します。見つからない場合は、そのプロトタイプが呼び出されます。したがって、オブジェクトのプロトタイプを設定すると、プロトタイプチェーンを調整できます。

あなたの質問に答えるには、何も必要ありません。それはあなた次第です。コードの再利用はあなたが望むものであり、継承はそれを実現する方法です (Stoyan Stefanov - JavaScript パターン)。JavaScript では、より多くの方法でコードを再利用できます。

さらに、これは常に現在のオブジェクトではなく、現在のコンテキストにバインドされます。

于 2013-03-07T08:18:27.697 に答える