Javascriptinheritance; 电话和原型

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

说我有一个基类“动物”

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); 

实现inheritance还不够吗?

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

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

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

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

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

 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 ,但使用与调用函数相同的函数。

Dog.prototype = new Animal(); 设置原型的原型。 但是, Dog.prototype = Object.create(Animal.prototype)可能更正确。

一个代码示例值得千言万语:)

 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成员不会被inheritance。 此外, Dog实例不会被视为Animal实例。

在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'); 

第二步可以帮助您inheritance原型方法。 想象一下,我们有更复杂的类:

 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' 

你可以在这里试试

这里我们定义Animal的构造函数

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

然后为Dog定义构造函数,并从内部调用Animal的构造函数。 就像我们在基于类的面向对象设计中做super()一样。

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

然后我们通过使用Animal原型中定义的方法来构建Dog的原型。 这里它没有克隆Animal方法,但是在DogAnimal之间设置了一个链接,使用它来重新使用Animal的方法

 Dog.prototype = new Animal(); 

并继续扩展它添加更多方法

 Dog.prototype.showName = function(){ // do something }