到底原型是个什么鬼?

先贴一篇文章

写了这么久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();
}
 
 
原文地址:https://www.cnblogs.com/tom-chang/p/5591474.html