3

要在Javascript中实现继承,通常执行以下2个步骤;

假设我有一个基类“动物”

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

我现在想从中派生一个子类“Dog”。所以我会说

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

所以我从派生类构造函数中调用我的父类构造函数。第二步,设置原型如下;

Dog.prototype = new Animal();

现在我可以从派生类 Dog 中访问任何基本的“Animal”类属性。

所以我的问题是为什么这两个步骤是必要的?如果我们只是使用调用基类构造函数

Animal.call(this,name);

这还不足以实现继承吗?

为什么我们需要使用设置原型属性Dog.prototype = new Animal();

我想了解上述两个步骤中的每一个的作用是什么?

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

第二步帮助你继承原型方法。想象一下,我们有更复杂的类:

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 中没有类,也没有子类。

call 和 apply 在不同的“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

这里我们定义了构造函数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

首先要了解的是,在 JavaScript 中没有经典的继承,我们从 Java、C# 等 C 语言中了解的机制。在 JavaScript 中,可以通过使用原型继承来实现代码重用。我们唯一拥有的是对象,即存活且不需要实例化的代码块。例如:当在对象上调用函数时(如方法),检查当前对象是否知道该函数。如果未找到,引擎将其称为原型(这是另一个对象)并检查函数名称是否已知并且可以调用。当没有找到时,它的原型被调用等等。因此,设置对象的原型可以编排原型链。

回答你的问题:没有什么是必要的,这取决于你想要什么。代码重用是您想要的,而继承是您可以实现这一点的方式(Stoyan Stefanov - JavaScript 模式)。在 JavaScript 中,有更多的方法可以重用代码。

此外, this 绑定到当前上下文,并不总是当前对象。

于 2013-03-07T08:18:27.697 回答