前言:
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
这里我们可以看出来,原型链到此为止。