Javascript继承;电话和原型

时间:2013-03-07 07:51:54

标签: javascript jquery inheritance prototypal-inheritance

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

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

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

我现在想从同一个派生出一个子类“狗”。所以我想说

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

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

Dog.prototype = new Animal();

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

所以我的问题是为什么这两个步骤是必要的? 如果我们只使用

调用基类构造函数
Animal.call(this,name);

还不足以实现继承吗?

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

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

6 个答案:

答案 0 :(得分: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)可能更正确。

答案 1 :(得分: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的实例。

答案 2 :(得分: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'

您可以尝试here

答案 3 :(得分: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');

答案 4 :(得分: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
}

答案 5 :(得分:0)

首先要理解的是,在JavaScript中没有经典的继承,我们从C语言中知道的机制,如Java,C#等堡垒。在JavaScript中,可以使用原型继承来完成代码重用。我们唯一拥有的是对象,代码块,它们还活着并且不需要实例化。例如:当在对象上调用函数时 - 就像方法一样,检查当前对象是否已知该函数。如果没有找到,引擎会将其称为原型(这是另一个对象),并检查函数名称是否已知且可以调用。如果没有找到,则会调用原型,依此类推。因此,设置对象的原型可以编排原型链。

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

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