面向对象里的原型与原型链

一、原型与原型链

  想要了解面向对象中的原型链,我们就要先了解什么是组成原型链的原型。

  在Javascript中,原型也是一个对象,通过原型可以实现对象的属性继承,Javascript的对象中都包含了一个Prototype内部属性,这个属性所对应的就是该对象的原型。

  在Javascript中,包含一个“constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数。

//封装
function Person(_name,_age,_sex){
    this.name=_name;
    this.age=_age;
    this.sex=_sex;
}
//原型
Person.prototype={
   constructor:Person, info:
function(){ console.log("My name is "+this.name); }, se:function(){ console.log("I‘m a"+this.sex); } }

var per=new Person("Lihua",18,"boy");
console.log(per.constructor);
per.info();

  在上面的这段代码里,首先构造函数,然后再写这个对象的原型,我们在声明一个新对象的时候,使用constructor可以查看新new的对象的构造函数。

  使用per.info()我们就调用了原型里的info属性。

二、原型链

  我们知道在面向对象里每个对象和原型都有原型,对象的原型指向原型对象,为父的原型又指向父级的父级,这种原型一层一层连接起来就构成了原型链。

  在了解原型链之前,我们还需要了解原型的继承。

 1 //封装
 2 function Dog(_variety,_age,_sex,_color){
 3     this.variety=_variety;
 4     this.age=_age;
 5     this.sex=_sex;
 6     this.color=_color;
 7 }
 8 //原型
 9 Dog.prototype={
10     vari:function(){
11         console.log("品种:"+this.variety);
12     },
13     col:function(){
14         console.log("颜色:"+this.color);
15     }
16 }        
17 //构造函数继承
18 function Smalldog(_variety,_age,_sex,_color,_height){
19     Dog.call(this,_variety,_age,_sex,_color);
20     this.height=_height;
21 }
22 var Mydog1=new Smalldog("金毛",7,"男孩","黄","30cm");
23 console.log(Mydog1.height); 
24 //原型继承
25 Smalldog.prototype=new Dog();
26 Smalldog.prototype.hit=function(){
27     console.log(this.height);
28 }
29 var Mydog2=new Smalldog("金毛",7,"男孩","黄","30cm");
30 console.log(Mydog2.age,Mydog2.height);
31 Mydog2.hit();       

  首先我们在1~16行代码封装了一个构造函数和原型,我们再在17~23行把Dog这一类的属性继承过来,也就是构造函数继承,接下来就是要讲的原型的继承。

  我们让Smalldog的原型等于Dog的原型,然后再给Smalldog的原型新添加一个hit属性,这个过程就是Smalldog继承了它父级的属性,并且新添加了属于自己的属性hit。

  新建一个对象之后我们来查看一下它的hit属性,我们就可以看到,Smalldog不仅有Dog原型中的vari和col属性,也有hit属性。

  上面那么多代码中,最关键的就是下面这段代码,使用prototype来实现原型的继承。

Smalldog.prototype=new Dog();
Smalldog.prototype.hit=function(){
    console.log(this.height);
}

三、原型链

  我们使用原型继承一层一层的构造原型,还是拿上面那段代码来举例。

 1 //封装
 2 function Dog(_variety,_age,_sex,_color){
 3     this.variety=_variety;
 4     this.age=_age;
 5     this.sex=_sex;
 6     this.color=_color;
 7 }
 8 //原型
 9 Dog.prototype={
10     vari:function(){
11         console.log("品种:"+this.variety);
12     },
13     col:function(){
14         console.log("颜色:"+this.color);
15     }
16 }        
17 //构造函数继承
18 function Smalldog(_variety,_age,_sex,_color,_height){
19     Dog.call(this,_variety,_age,_sex,_color);
20     this.height=_height;
21 }
22 var Mydog1=new Smalldog("金毛",7,"男孩","黄","30cm");
23 console.log(Mydog1.height); 
24 //原型继承
25 Smalldog.prototype=new Dog();
26 Smalldog.prototype.hit=function(){
27     console.log(this.height);
28 }
29 var Mydog2=new Smalldog("金毛",7,"男孩","黄","30cm");
30 console.log(Mydog2.age,Mydog2.height);
31 Mydog2.hit();       

  当我们想调用某个属性的时候,比如Mydog2.col(),它首先会在Mydog2的构造函数里寻找这个属性,再到Mydog2的原型里去寻找,如果Mydog2原型里还是没有这个属性,那么就会去原型对象的原型里也就是Dog的原型里去寻找,如果最终的父级的原型里(object.prototype)里依旧没有这个属性,那么就会打印出null。

  这样一条查找属性的路径和方法,就叫做原型链。

四、总结

原型链:

      ①在访问对象的某个成员的时候会先在对象中找是否存在。

      ②如果当前对象中没有就在构造函数的原型对象中找。

      ③如果原型对象中没有找到就到原型对象的原型上找。

      ④知道Object的原型对象的原型是null为止。

  

原文地址:https://www.cnblogs.com/zheng577564429/p/6535252.html