__proto__ 和 prototype的关系

图片描述

__proto__ 和 prototype的关系


先上答案:

​ 对象上都有__proto__属性(函数也是对象)浏览器

​ 通常状况下对象的__proto__属性指向该对象的构造函数的原型对象。函数

​ 函数上才有prototype属性,该属性指向该函数的原型对象。ui

OK,下面来详细解释一下this

什么是__proto__

这个实际上是一个 internal slot (翻译成内置槽?),叫作 [[ prototype ]] ,也称为隐式原型。在js里全部的普通对象都会有。它的值要么是 null(原型链的最终), 要么仍是一个对象。spa

以前并无一个标准的方法来访问这个值,可是大多数浏览器都支持经过用.__proto__来获得它的值。因此 [[ prototype ]] 就被叫成了 __proto__ 。直到ES5中增长了标准的方法 :Object.getPrototypeOf()prototype

All ordinary objects have an internal slot called [[Prototype]]. The value of this internal slot is either null or an object and is used for implementing inheritance.

ECMAScript Language Specification翻译

什么是prototype

全部用 function 语句、函数字面量或者 Function 构造函数定义的函数都会同时自动建立一个 prototype 属性,指向该函数的原型对象。code

另外,经过Function.prototype.bind()建立的函数没有 prototype 属性。对象

NOTE 1 Function objects created using Function.prototype.bind are exotic objects. They also do not have a prototype property.

ECMAScript Language Specificationblog

这里 Function 的 prototype 有点不一样,实际上它是内部对象%FunctionPrototype%,它自己是一个内置函数对象。

它有一些特殊的规则,好比 Function.prototype.length === 0 等

The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.

NOTEThe Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

The value of the [[Prototype]] internal slot of the Function prototype object is the intrinsic object %ObjectPrototype% (19.1.3). The initial value of the [[Extensible]] internal slot of the Function prototype object is true.

The Function prototype object does not have a prototype property.

The value of the length property of the Function prototype object is 0.

The value of the name property of the Function prototype object is the empty String.

ECMAScript Language Specification

Object 的 prototype 也有一点不同,它实际上是内部对象%ObjectPrototype%,它自己是一个普通对象。

作为对象它的 __proto__ 也就是 [[prototype]] 值为 null 。

Object.prototype上挂载着valueOf,toString等方法。

The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an ordinary object.

The value of the [[Prototype]] internal slot of the Object prototype object is null and the initial value of the [[Extensible]] internal slot is true.

ECMAScript Language Specification

二者的关系

先上一张神图 :

图片描述

每一个被构造函数建立出来的对象都有一个隐式引用,指向其构造函数的prototype属性的值。此外,一个原型可能对它的原型有一个非空的隐式引用,以此类推,就叫作原型链。

Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s "prototype" property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.

ECMAScript Language Specification

看图说话

构造函数 Foo 的原型属性 prototype 指向了原型对象 Foo.prototype 。f1, f2 是Foo的实例,经过指向原型对象的__proto__ 就能够继承原型对象上公有的方法。同时,Foo.prototype 上constructor 属性指回 构造函数 Foo。

构造函数Foo自己也是对象,因此也有 __proto__ ,指向了Foo的构造函数的原型对象,也就是Function.prototype。

原型对象也是对象,因此也有 __proto__ ,指向Object.prototype。最终Object.prototype.__proto__指向 null。

(完) :)

相关文章
相关标签/搜索