首先,js的數據結構有 原始類型(5種):Boolean、Number、String、Null、Underfined,數據結構
而後是引用類型:Array、Date、Error、RegExp、Function、Object,注意這裏,引用類型的返回值,其實只有2種,也就是Function和Object,用typeof就能夠判斷出。函數
js一切都是對象,Function天然也是對象,甚至Function比Object的功能更強大,new Function出來的變量,好比:spa
function Foo(){} var foo = new Foo(); typeof Foo //function typeof foo //object
Function和Object的區別,重點來了,Function有prototype屬性,而Object是沒有的:prototype
console.log(Foo.prototype) //Object console.log(foo.prototype) //undefined
下面來講原型鏈和繼承:指針
js是經過__proto__來明確繼承 的關係,__proto__不一樣於prototype,由於__proto__是對象的屬性,所以Function和Object都有這個屬性,在強調一下,Object是沒有prototype的,而Function和Object都有__proto__屬性。code
而後看一下__proto__這個屬性是怎麼工做的,例如:對象
var a = {aa:1}; var b = {bb:2}; var c = {cc:3}; a.__proto__ = b; b.__proto__ = c; console.log(a.aa);//1 console.log(a.bb);//2 console.log(a.cc);//3
這就簡單的實現了繼承,也就是原型以及原型鏈。既然__proto__解決了繼承的問題,那麼prototype幹什麼呢?固然有它本身的用處,再回到上一個例子:blog
function Foo(){} var foo = new Foo(); console.log(Foo.prototype===foo.__proto__)//true
精髓就在於此:經過new構造函數構造出來的實例對象foo,它的__proto__屬性,實際上是一個指針,它指向的是構造函數Foo的prototype屬性。繼承
爲了便於之後複習,我總結一下上面內容,可能有理解不對的地方,但願大神指正。原型鏈
一、object.__proto__指向他的原型對象,若是他的原型對象的__proto__還有上面的原型對象,好比:
var a = {aa:1}; var b = {bb:2}; var c = {cc:3}; a.__proto__ = b; b.__proto__ = c;
那麼,a就繼承了c的屬性和方法,這就是原型和原型鏈,繼承就是這樣實現的。
二、關於prototype和__ptoto__:
首先,Function和Object都屬於引用類型(平級的),都是對象,所以,都具備__proto__屬性。
其次,Function有prototype屬性而Object沒有。
prototype和__ptoto__二者的關係是,實例對象的__proto__指向的就是構造函數的prototype:
function Foo(){} var foo = new Foo(); console.log(Foo.prototype===foo.__proto__)//true