要在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();
设置原型属性?
我想了解上述两个步骤的作用是什么?
答案 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
中的方法,但是在Dog
和Animal
之间设置了一个链接,使用它来使用Animal
中的方法
Dog.prototype = new Animal();
继续扩展它添加更多方法
Dog.prototype.showName = function(){
// do something
}
答案 5 :(得分:0)
首先要理解的是,在JavaScript中没有经典的继承,我们从C语言中知道的机制,如Java,C#等堡垒。在JavaScript中,可以使用原型继承来完成代码重用。我们唯一拥有的是对象,代码块,它们还活着并且不需要实例化。例如:当在对象上调用函数时 - 就像方法一样,检查当前对象是否已知该函数。如果没有找到,引擎会将其称为原型(这是另一个对象),并检查函数名称是否已知且可以调用。如果没有找到,则会调用原型,依此类推。因此,设置对象的原型可以编排原型链。
回答你的问题:没有必要,它取决于你想要的东西。代码重用是您想要的,继承是您实现这一目标的方式(Stoyan Stefanov - JavaScript Patterns)。在JavaScript中,有更多方法可以重用代码。
此外,它绑定到当前上下文,并不总是当前对象。