咱們建立的每一個函數都有一個prototype(原型)屬性,這個屬性是一個對象,它的用途是包含能夠由特定類型的全部實例共享的屬性和方法。(這個對象下面有個屬性,這個屬性是另一個對象的應用 ,這個屬性就是一個對象。)函數
- prototypespa
是顯式原型,它是指向函數的原型對象。(函數建立以後就會產生prototype屬性)prototype
funcition這個特殊的對象,除了和其餘對象同樣有_proto_屬性以外,還有本身特有的屬性——原型屬性(prototype),這個屬性是一個指針,指向一個對象,這個對象的用途就是包含全部實例共享的屬性和方法(咱們把這個對象叫作原型對象)。prototype是經過調用構造函數而建立的那個對象實例的原型對象。原型對象也有一個屬性,叫作constructor,這個屬性包含了一個指針,指回原構造函數。指針
一、顯式原型的做用:用來實現基於原型的繼承與屬性的共享code
二、使用原型對象的好處:是可讓全部對象實例共享它所包含的屬性和方法,沒必要在構造函數中定義對象實例的信息,而是能夠將這些信息直接添加到原型對象中。對象
- __proto__blog
是隱式原型,它所指向的是建立這個對象的函數(constructor)的prototype ,能夠經過 object.setPrototypeOf();來得到一個對象的proto屬性繼承
function是對象,function的原型prototype也是對象,它們都會具備對象共有的特色。即:對象具備屬性__proto__,每一個對象都會在其內部初始化一個屬性,就是__proto__,當咱們訪問一個對象的屬性 時,若是這個對象內部不存在這個屬性,那麼他就會去__proto__裏找這個屬性,這個__proto__又會有本身的__proto__,因而就這樣 一直找下去,也就是咱們平時所說的原型鏈的概念。__proto__可稱爲隱式原型,一個對象的隱式原型指向構造該對象的構造函數的原型,這也保證了實例可以訪問在構造函數原型中定義的屬性和方法。ci
一、隱式原型的做用:構成原型鏈,一樣用於實現基於原型的繼承。舉個例子,當咱們訪問obj這個對象中的x屬性時,若是在obj中找不到,那麼就會沿着__proto__依次查找。原型鏈
function a() { } a.prototype.name = "1" var b = new a() //這個並非構造函數專有,每一個函數都會有一個prototype屬性,這個屬性是一個指針,指向一個對象,記住只有函數纔有,而且經過bind()綁定的也沒有。 console.log(b.name)// 1 console.log(a.prototype) // {constructor: ƒ} console.log(a.__proto__) // ƒ () { [native code] } //a做爲構造函數時的prototype屬性與a做爲普通函數時的__proto__屬性並不相等 console.log(a.prototype === a.__proto__);//false //a做爲一個普通函數調用時,它的構造函數是內置對象Function,因此它指向的原型對象,就是Function.prototype,其實這個和console.log(b.__proto__ == a.prototype)是同樣的道理 console.log(b.__proto__) // {constructor: ƒ} console.log(Function.prototype) //ƒ () { [native code] } console.log(a.__proto__ === Function.prototype);//true console.log(b.__proto__ === a.prototype) // true //a做爲構造函數時,它的原型,和它的原型的原型 console.log(a.prototype); //a{} console.log(a.prototype.__proto__); // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ,ƒ…} //a做爲普通函數時,它原型的原型 console.log(a.__proto__.__proto__); // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ,ƒ…} console.log(a.__proto__.__proto__ === a.prototype.__proto__); //true
- 總結
全部對象都有__proto__屬性,函數這個特殊對象除了具備__proto__屬性,還有特有的原型屬性prototype。prototype對象默認有兩個屬性,constructor屬性和__proto__屬性。prototype屬性能夠給函數和對象添加可共享(繼承)的方法、屬性,而__proto__是查找某函數或對象的原型鏈方式。constructor,這個屬性包含了一個指針,指回原構造函數。
prototype和__proto__都指向原型對象,任意一個函數(包括構造函數)都有一個prototype屬性,指向該函數的原型對象,一樣任意一個構造函數實例化的對象,都有一個__proto__屬性(__proto__並不是標準屬性,ECMA-262第5版將該屬性或指針稱爲[[Prototype]],可經過Object.getPrototypeOf()標準方法訪問該屬性),指向構造函數的原型對象。