彻底弄懂原型链

写在前面

对于初学者而言,原型链是一个比较难懂的概念,而且百度上解释原型链的五花八门,看得越多就越觉得不懂,我就是这样,看得越多,就越觉得原型链这个概念深不可测,但幸好,看到最后,自己可以融会贯通了。

弄懂原型链的作用

原型链的作用是用来继承的,很多文章都在讲原型链的原理是怎么样,但对如何使用原型链实现继承都只字未提。在看这篇文章前,我希望读者们对原型链已经有一定程度的了解了,至于接不接受我对原型链的看法,需要读者自己去甄别了,所谓尽信书不如无书,在检验理论是否正确的时候,需要读者记住实践是检验真理的唯一标准,一定要动手实践。

下面这是一个如何使用原型链实现继承的例子:

function A()
{

}
function B() { 

 this.name="你好";

};

A.prototype =  new  B();
//为什么要加上这一句?
A.prototype.constructor=A;

var a=new A();
//a.name=‘你好’
console.log(a.name);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
原型链中三个重要原则:

原则1: 任何一个构造函数都有一个prototype属性,指向一个对象,称这个对象为prototye对象

原则2: 每个对象都有一个constructor属性,指向这个对象的构造函数。JavaScript
规定:构造函数的prototype对象的constructor属性指向它本身。即:

function A(){
}
alert(A.prototype.constructor==A);//true
 
 
  • 1
  • 2
  • 3

原则3: 构造函数(Function)拥有prototype属性,对象(除Object)拥有_ proto_ 属性。且,构造函数所生成的实例对象的_ proto _属性指向构造函数的p rototype属性。即:

function A(){
}
var a=new A();
alert(a.__proto__==A.prototype);//true
 
 
  • 1
  • 2
  • 3
  • 4
弄懂头疼的_ proto_ 和prototype

当我看见百度上解释原型链的文章里一会是_ proto_ ,一会是prototype, 我就开始一个头两个大。直到我明白了它两者之间的关系后,突然就豁然开朗。

_ proto_和prototype的关系 :一个实例对象拥有一个指向原型的proto属性(即原则3: 实例对象的_ proto_指向构造其构造函数的prototype),_ proto 属性是不可见的,但是在某些浏览器中以 proto _的形式将该属性暴露出来供开发者调试,该属性被称之为“内部原型链”(该原型链才是真正的原型链),而prototype是留给开发者们用来显式地定义原型链的。他们的关系可以说是一表一里,一个是外在,一个是实质。

这里写图片描述

彻底弄懂原型链

在经过上面的铺垫后,下面这张图应该很好理解:

这里写图片描述

真正的原型链即是 _ prpto _属性练起来的那条链!

好了,到这,我们该处理遗留的历史问题了,将第一个例子在稍稍改写一下,更加直观

function A()
{

}
function B() { 

 this.name="你好";

};

var b=new B();
A.prototype = b ;
//为什么要加上这一句?A.prototype.constructor=A;将这句去掉,看alert的结果是什么
alert(A.prototype.constructor);
var a=new A();
//a.name=‘你好’
console.log(a.name);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

可以看出,如果去掉A.prototype.constructor=A这一句的话,我们alert的结果是 function B() {

this.name=”你好”;

};这是为什么呢?

根据原则2,“构造函数的prototype对象的constructor属性指向它本身”,在

var b=new B();
A.prototype = b ;
 
 
  • 1
  • 2

这两句的作用下,A.prototype的对象是b,而b是函数B() new出来的,当然,A.prototype.constructor的结果是B()。

所以这就需要我们手动的调整constructor的指向,

var b=new B();
A.prototype = b ;
A.prototype.constructor=A
 
 
  • 1
  • 2
  • 3
结语

所以,对于原型链,会用继承,并且知道背后的原理就行啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值