关于JavaScript的面向对象和继承有利新手学习(2)


garfield.__proto__ === Cat.prototype
true //看到了吗? `Cat.prototype` 现在是garfield对象的原型


现在,我们给Cat.prototype添加一个方法,添加之后,该方法可以被garfield访问到

复制代码 代码如下:


Cat.prototype.greet = function(){
console.log('Meow, I am ' + this.name)
}
garfield.greet()
"Meow, I am Garfield"


其他的Cat的实例也可以访问到

复制代码 代码如下:


var felix = new Cat('Felix')
felix.greet()
"Meow, I am Felix"


因此,在JavaScript中,方法是依赖于对象的原型(prototype)而存在的。

实际上,我们也可以为garfield添加方法,它会覆写Cat.prototype中的同名方法,如下所示:

复制代码 代码如下:


garfield.greet = function(){
console.log("What's new?");
};
garfield.greet();
"What's new?"


但这并不会影响到其他的对象

复制代码 代码如下:


felix.greet();
"Meow, I am Felix"


因此,JavaScript中,方法可以直接和一个对象关联,可以和对象的原型关联,也可以和对象的任意一个父辈对象关联,即,可以和原型链(prototype chain)的任意一环关联。继承也就是这样实现的。

要创建一个二级原型链(prototype chain),我们首先需要创建另一个构造函数(constructor),叫Animal如何?

复制代码 代码如下:


function Animal(){
}


接下来,我们需要将Cat.prototype的原型指向一个Animal的对象,这样一来,Cat的实例就会继承所有的Animal的方法。因此,我们将Cat.prototype的值设置为Animal的实例,如下所示:

复制代码 代码如下:


Cat.prototype = new Animal();


除此之外,我们还要告诉新的Cat.prototype,它实际上是Cat的一个实例:

复制代码 代码如下:


Cat.prototype.constructor = Cat // 让`Cat.prototype` 知道它是Cat的一个实例


虽然这样做的目的主要是为了类之间的层次关系,但通常还是有必要这样做的。

现在,既然继承自Animal.prototype和Cat.prototype的对象是属于动物类,那么所有Cat的实例也间接的继承自Animal.prototype。如果我们给Animal.prototype添加一个新方法,那么,所有的Cat的实例也能够访问到该方法。

复制代码 代码如下:


Animal.prototype.breed = function(){
console.log('Making a new animal!');
return new this.constructor();
};
var kitty = garfield.breed();
Making a new animal!


通过上面的代码我们就实现了继承,简单吧。

结语
虽然JavaScript中基于原型的继承很怪并且需要花一些时间才能习惯,但是他的核心思想是很简单的。只要你真正理解了这些本质上的概念,你就会有信心在这些良莠不齐的代码中驾驭JavaScript的OO。(完)^_^

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wddgxj.html