__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。

(完) :)

相關文章
相關標籤/搜索