写了这么久JS,从来没有真正去思考过这个问题,在java时代我们是
class Animal{
public myFunc(){
}
}
class Dog extend Animal{
public sayWangwang(){
}
}
haqishi=new Animal();
haqishi.myFunc();
haqishi.sayWangwang();
///////////
来到了javascript的时代,我们没了class
Dog还想用Animal的方法,该怎么办
一定要建立一些关系,其中有两个问题是必须解决的
1.继承了Animal的Dog可以调用Animal上的方法,且不可轻易修改
2.Dog实例同时可以拥有自己的同名方法,有同名方法时就先用自己的
javascript是过程性语言
我们需要用一种简单的方法:建立一个审查链条,这个链条上是实例对象,他们有自己的方法,
在这条链上寻找方法,找到了就可以返回调用。同时this指针要保证他的正确性
来路演一下:
var Animal=new function (name){
this.name=‘animal‘||name;
}
//此时
一个名叫Animal函数实例被创建了,我们不去思考它之前的东西,假设它有一个属性是对象,姑且叫做Animal.Dad,我们在Animal.Dad上挂一个函数
Animal.Dad.breath=function(){console.log(this.name+‘xixi huhu‘)}
//接下来我们来创建一个animal
var animal=new Animal(‘dog‘);
//这时有一些奇妙的事情发生了,我们将它分成三步
1.建立空对象2.建立和Animal的联系3.调用Animal的构造函数
var
animal = {};//建立一个对象,这一步没有疑问
animal._dad_=Animal.Dad;//我们创建一个叫做_dad_的属性将他指向Animal.Dad;
Animal.call(animal,‘dog‘);//这时animal拥有了Animal函数上的所有方法属性
当我们调用animal.breath()时这个方法本身是不存在的,去内部属性_dad_上找,发现有
这时实际的过程则是:Animal.Dad.breath.call(animal);
到这里我们实际上已经解决了对象继承的初步,
那么在JAVASCRIPT里,Animal函数的Dad的真名叫做prototype,而animal实例的内部属性_dad_在标准浏览器里名字则是__proto__;
//再接下来我们试试创造一个叫做Dog的方法
var Dog=new Function(){
}
Dog.prototype.wangwang=function(){
console.log(‘wangwang‘)
}
这时我们的Dog拥有了自己的Dad对象上有一个方法叫做wangwang
那么我们现在想让这个Dog对象拥有Animal对象的方法breath
Dog.prototype.breath=Animal.prototype.breath;
这是一种解决方案,
如果有很多方法都想继承过来
我们可以循环遍历,这是一种办法
还有没有其他方法呢
Dog.prototype=Animal.prototype;
Dog.prototype.wangwang=function(){
console.log(‘wangwang‘)
}
似乎可以,但是很快发现这不是继承,这是修改
如何让Dog.prototype指向一个有Animal方法的对象,同时却不会破坏Animal.prototype呢
方法是有的,我们需要在Dog.prototype和Animal.prototype之间创建一个关联对象,我们叫他海龟HG
var HG=function(){
}
HG.prototype=Animal.prototype;//让HG拥有Animal上的所有原型方法
var hg=new HG();//创建一个HG对象,它拥有了Animal的原型方法
Dog.prototype=hg;//将Dog函数的原型指向实例,hg
//接下来我们调用
var xiaohuier=new Dog(‘xiaohuier‘);
xiaohuier.breath();//此时就像上面讲的创建对象时的第三步,追溯到了HG(也是Animal)原型方法
//修改时
Dog.prototype.eatBone=funciton(){
}//等价于hg.eatBone,这时Animal的原型已经被HG成功了分开了。
//最后我们把这个继承封装成一个函数
function extend(child,parent){
var F=function(){
}
F.prototype=parent.prototype;
child.prototype=new F();
}