javaScript原型链详解

首先我们要清楚地知道原型链的本质:原型链是一种关系,实例对象和原型对象之间的关系

接下来就来细细分析,我们先看一段代码:

这里定义了一个构造函数Person(),然后创建了两个实例对象per,per2。我们来看一下打印的结果:

 

看输出很正常,没有什么问题,但是大家有没有发现,两个实例对象有一个相同的方法,虽然方法名一样,

但它们在内存里是存储在不同的地方的,也就是说,当有很多个实例对象的时候,你内存空间就爆炸了,浏览器

直接被干掉,所以我们不能直接在构造函数里声明对象的方法,那我们在哪里声明呢?

我们来看一段代码及其输出结果:

 

 

看最后一条输出结果为true,相信大家也明白这两个指向的是同一块内存空间,也就是同一个对象。也许有小伙伴会困惑,Object.getPrototypeOf(per) 这个是啥?实例对象不是通过__proto__来访问原型的吗?

OK,我们去看一下MDN文档:

 

正如文档所说,__proto__已经被弃用了,我们应该习惯使用Object.getPrototypeOf(per) 这种方式来访问原型,

注意:Object.getPrototypeOf() 是给实例对象来访问原型的,构造函数通过属性prototype来访问原型。

所有的构造函数都有一个原型对象,这个原型对象就是用来解决数据共享问题,用来节约内存空间的。

我们在原型对象里面声明方法,当通过构造函数去声明实例,如果通过实例调用了一个属性/方法,找不到就会到

原型上去找,一直找到原型的尽头,最后找不到则输出undefined,如果是方法则抛出错误。

所以回到文章开头那段代码所面临的问题,正确的声明方法应该是这样子的:

现在实例对象,构造函数,以及原型对象之间的关系是这样子的,我画一个图来表示:

 

我们打印一下原型对象看看吧:

我们可以看到,这个对象有一个constructor属性,后面的值已经告诉我们了,它是构造函数。我们来验证一下

它的指向是不是构造函数在内存中的地址:

打印结果为true,也就是说这两个东东在内存里面是同一块,所以现在实例对象,构造函数,以及原型对象的关系变成:

 

这就是所谓的原型链了,原型链其实就是实例对象,构造函数以及原型对象之间的关系而已。

也许有小伙伴脑洞大开,会想,原型对象的原型对象是什么呢?终点在哪?以这个为例子说:

Person.prototype指向的原型,也就是Object.getPrototypeOf(Person.prototype)指向哪里呢?

那么我问问大家,函数其实是什么?

没错,javaScript除了基本数据类型外,其他都可以看作对象。也就是Object,那么

Object.getPrototypeOf(Person.prototype)跟Object.prototype是否指向同一个空间呢?

输出为true,也就是说这两个是同一个东东。

那么Object.getPrototypeOf(Object.prototype) 是什么呢?

大家可以试试看,可以剧透一点,是原型链的尽头噢。

喜欢可以点点关注,期待与大家一起进步。

 

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酒客->老张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值