论构造函数的原型是谁

论构造函数的原型是谁

我们知道,作为构造函数,比如Object,它们都有一个属性prototype,在new一个新的对象的时候,会把这个对象的原型设置为这个prototype属性指向的对象。

下面的语句可以证明这一点。

let o = new Object
console.log(Object.getPrototypeOf(o) === Object.prototype)

image-20220709205927667

我之前也一直以为,构造函数Object的原型也是prototype,因为这个属性也太富有迷惑性了,光看名字很容易让人这样想。

直到今天,我发现Object.__proto__Object.prototype不一样。

console.log(Object.__proto__)
console.log(Object.prototype)

image-20220709210405752

我便陷入了疑惑,在我之前的认知里,__proto__作为一个不太规范的属性,是用来获得某个对象的原型的,而prototype从字面意义很明显也是获得原型的。

那按理说这两个属性应该是返回相同的值,现在却不一样了?

现在我们用规范设定的标准方法Object.getPrototypeOf()来获取Object的原型,看看到底__proto__还是prototype返回的结果正确。

console.log(Object.__proto__)
console.log(Object.prototype)
console.log(Object.getPrototypeOf(Object))
console.log(Object.getPrototypeOf(Object) === Object.__proto__)

image-20220709211511982

可以看到,__proto__属性返回的结果才是Object构造函数的真实原型。

所以实际上,构造函数的prototype属性只是用作new一个新对象的时候把它赋值给新对象的原型用,至于构造函数本身的原型,和它八竿子打不着。

从这张总结图中,我们可以看到,所有构造函数的原型都指向了一个匿名函数。

Object的原型也是,在node中输出出来有些问题,浏览器的终端里看的很清楚。

image-20220709212052455

image-20220709212127355

构造函数的原型是一个函数,听起来很奇怪对吧?原型原型,原型是原型对象的简称啊,原型不应该是一个对象嘛?

这实际上就告示这JavaScript讲函数式语言和面向对象的语言结合的结果。在JS中函数是对象态的,函数也是一个对象。

所以node中输出出来,是一个{},其实也没什么问题,应该函数也是对象,里面为什么是空的,只是因为这个函数对象里面的属性都是不可枚举的。

image-20220709212539558

可以看到这个函数对象里面,有着我们常用的 call,apply,bind,这些方法都定义在所有函数的原型里面——一个匿名函数。

值得注意的是,我们之前提出了一个论断 大部分构造函数的prototype属性和__proto__属性完全不一样

因为__proto__属性指向构造函数自己的原型,而prototype属性指向实例的原型。

而有一个构造函数,它的原型和它构造出来的实例的原型是同一个,它就是Function

image-20220709213106524

这是构造函数Function构造出来的也是函数所必要的。

它本身也是函数,它构造出来的也是函数,它们作为函数,都需要函数所公用的一些东西,所以它们需要拥有共同的原型,即那个匿名函数。

还有一点从那个总结图中可以看出来,所有构造函数的原型,即那个匿名函数,指向了那个原型链的尽头,即Object.prototype,即所有普通对象【Object构造函数产生的对象】的原型。

这也完美诠释了JS中函数也是对象的含义。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值