_proto_和 prototype的关系

本文探讨了JavaScript中_proto_和prototype的区别。_proto_作为内部插槽[[Prototype]]的别名,用于实现继承和原型链,而prototype是函数对象上的属性,指向自身的[[Prototype]]。尽管两者不相同,但它们共同构成了JavaScript的原型继承机制。Object.getPrototypeOf()是访问[[Prototype]]的标准方法,而prototype属性在某些情况下(如Function对象)不具有自身原型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

​1、两者完全是两个东西!!
2、所有都有_proto_属性,初始值该对象的构造函数的原型对象(ptoto);
​3、函数上和内置对象上才有prototype属性,初始值是本身的_ptoto_。

_proto_

这其实只是一个别名,proto_的真实本质是一个internal slot(内置插槽)[[Prototype]],注意这里的[[Prototype]]与我们标题里的prototype是两个东西!!只是因为之前并没有一个标准的方法来访问这个值,但是大多数浏览器都支持通过用_proto_来得到它的值。所以 [[ prototype ]] 就被叫成了_proto。直到ES5中增加了标准的方法 :Object.getPrototypeOf()

ECMA-262: All ordinary objects have an internal slot called[[Prototype]]. The value of this internal slot is either null or anobject and is used for implementing inheritance.Data properties of the[[Prototype]] objeck are inherited(and visible as propertoes of thechild object)for the purpose of get access, but not for set access.Access properties are inherited for both get access and set access

注意ECMA标准中对[[Prototype]]的描述,实际上指明了这个内置插槽其实就是用来实现原型链的,也就是说我们平时所说的原型链,追溯原型链都是说的_proto_。

什么是internal slot
与property不同,internal slot不可以通过“.”或者“[]”直接访问,它们是用来记录对象内部状态的一系列键值对(伪属性)。只能通过提供的标准方法访问(也有可能根本没法访问或者根本没有被添加到对象中,只是在规范中被定义用来记录对象的内部状态);但是我们的操作却有可能影响到internal slot的值。
https://stackoverflow.com/questions/33075262/what-is-an-internal-slot-of-an-object-in-javascript
这里有一个有意思的讨论

prototype

prototype是一个内部对象%FunctionPrototype%或%ObjectPrototype%,而_proto_([[Prototype]])则是一个object;
prototype是一个属性可以直接访问,而_proto_([[Prototype]])则是一个内置插槽不可以直接访问。

Function 的 prototype 实际上是内部对象%FunctionPrototype%,也就是一个内置的函数对象。所有用 function 语句、函数字变量或者 Function 构造函数定义的函数都会同时自动创建一个 prototype 属性,指向该函数的[[Prototype]]。此外,通过Function.prototype.bind()创建的函数没有 prototype 属性。

ECMA-262:

The Function prototype object:

  • is the intrinsic object %FunctionPrototype%.
  • is itself a built-in function object.
  • accepts any arguments and returns undefined when invoked
  • does not have a [[Construct]] internal method;it cannot be used as a constructor with the new operator.
  • has a [[Prototype]] internal slot whose value is the intrinsic object %ObjectPrototype%.
  • does not have a prototype property.
  • has a “length” property whose value is 0.
  • has a name property whose value is the empty String

函数的prototype属性实际上还是一个函数,只是他没有了构造函数不能使用new来新建实例而已。注意这里有提及,函数的prototype是没有prototype属性的,也就是说这里其实是没有链的,但是我们注意到[[Prototype]]仍然存在,更加证实了其实原型链是指_proto_([[Prototype]])构成的链,prototype更像是一个分支产物。
但是也可以理解为我们平时说的基于原型链的继承就是用的prototype属性来完成的。

Object 的 prototype 是内部对象%ObjectPrototype%,而Object的_proto_([[Prototype]])则为null,也就是说原型链到了它这儿就停止了,但是它仍然具有prototype属性,Object.prototype上挂载着valueOf,toString等方法。

ECMA-262:

The Object prototype object:

  • is the intrinsic object %ObjectPrototype%.
  • is an immutable prototype exotic object.
  • has a [[Prototype]] internal slot whose value is null

这里我们可以看出来,原型链到此为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值