__proto__ 和 prototype的關係

圖片描述

__proto__ 和 prototype的關係


先上答案:

​ 對象上都有__proto__屬性(函數也是對象)

​ 一般情況下對象的__proto__屬性指向該對象的構造函數的原型對象。

​ 函數上纔有prototype屬性,該屬性指向該函數的原型對象。

OK,下面來詳細解釋一下

什麼是__proto__

這個其實是一個 internal slot (翻譯成內置槽?),叫做 [[ prototype ]] ,也稱爲隱式原型。在js裏所有的普通對象都會有。它的值要麼是 null(原型鏈的最終), 要麼還是一個對象。

之前並沒有一個標準的方法來訪問這個值,但是大多數瀏覽器都支持通過用.__proto__來得到它的值。所以 [[ prototype ]] 就被叫成了 __proto__ 。直到ES5中增加了標準的方法 :Object.getPrototypeOf()

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 屬性,指向該函數的原型對象。

另外,通過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 Specification

這裏 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。

(完) :)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章