在javascript中原型和原型鏈機制是最難懂的部分(沒有之一),同時也是最重要的部分,在學習的過程當中你可能認認真真的看了一遍但仍是徹底不懂書上說的什麼,的確是這樣的,我在學習的時候但是反覆看了四、5遍才初步理解了。 下面我把個人理解總結了一下但願對大家有一點幫助。javascript
講原型和原型鏈以前咱們先講基礎知識——js對象。什麼是對象呢? 這裏引用別人的一句話「js中一切皆對象」,先不用徹底明白,由於我也不明白,在後面的學習中慢慢理解。
首先在js中對象分爲函數對象和普通對象兩種,看下面的例子:java
function fun1(){}; var fun2 = function(){}; var fun3 = new Function(); var obj1 = new fun1(); var obj2 = {}; var obj3 =new Object(); console.log(typeof Object); // function console.log(typeof Function); // function console.log(typeof obj1); // object console.log(typeof obj2); // object console.log(typeof obj3); // object console.log(typeof fun1); // function console.log(typeof fun2); // function console.log(typeof fun3); // function
上面代碼中fun一、fun二、fun3是函數對象,obj一、obj二、obj3是普通對象,那麼怎麼區分呢? 很簡單,凡是經過 new Function() 建立的對象都是函數對象,其餘的都是普通對象,fun一、fun2歸根結底仍是經過 new Function() 建立的,所以也是函數對象。segmentfault
首先咱們來說普通對象,咱們經過一張圖來看看普通對象在建立時都作了些什麼。函數
1 var foo = { 2 x: 10, 2 y: 20 3 } 4 console.log(foo.__proto === Object.prototype) // true
上面的代碼中咱們建立了一個普通對象foo,並初始化了兩個屬性(自身屬性)x、y,同時在對象內部還自動建立了一個屬性__proto__,這個__proto__屬性其實是個指針,指向構造foo的構造函數的原型,這裏foo對象實際是經過 new Object 建立的,所以第4行代碼結果爲true. 這裏講到了Object.prototype就涉及到函數對象了,由於只有函數對象纔有prototype屬性,因此接下來咱們講函數對象。學習
用與上面相似的代碼來解釋:this
1 function foo() { 2 this.x = 10 3 } 4 foo.prototype.y = 20; 5 console.log(foo.__proto__); 6 console.log(foo.prototype);
當咱們建立foo函數時,初始化了一個自身屬性x = 10,同時函數對象中自動建立了一個prototype屬性和__proto__屬性,還爲foo建立了一個原型對象foo.prototype。其中__proto__屬性咱們上面已經講過了,而prototype屬性則指向foo新建立的prototype原型對象,這個原型對象中自動建立了一個constructor屬性,指向構造函數foo。
(注:原型對象prototype也是一個普通對象,所以會自動建立__proto__屬性,爲避免文章變得晦澀難懂,此處省略,後面再深刻講解)
執行第4行代碼,爲新建立的prototype原型對象添加了一個原型屬性y = 20。
執行五、6行代碼,咱們能夠看到控制檯打印出來的結果以下:spa
結果印證了咱們上面講的內容:1.__proto__指向foo的構造函數function 2.prototype指向foo的原型對象prototype 3.原型對象中constructor指向構造函數foo。prototype