前言:用了這麼久js,對於它的原型鏈一直有種模糊的不確切感,很不爽,隧解析之。javascript
本文主要解決的問題有如下三個:java
(1)constructor 和 prototype 以及實例之間啥關係?函數
(2)prototype是啥,__proto__又是啥,他們之間啥關係?spa
(3)若是改變一個 constructor 的 prototype,他的實例會發生什麼改變?prototype
ok,下面一個一個解決。3d
(1)constructor 和 prototype 以及實例對象三者之間啥關係?指針
舉例:對象
如上,當咱們建立一個函數,系統就會爲這個函數自動分配一個prototype指針,指向它的原型對象。而且能夠發現,這個原型對象包含兩個部分(constructor 和 __proto__)其中constructor指向函數自身。(這裏造成了一個小閉環)blog
當咱們將該函數做爲模版建立實例(new方法)的時候,咱們發現建立出的實例是一個與構造函數同名的object,這個object是獨立的,他只包含了一個__proto__指針(實例沒有prototype,強行訪問則會輸出undefined),這個指針指向上面提到的構造函數的prototype原型對象。ip
這時候咱們發現三者造成了一個大"閉環"。之因此加上引號,由於構造函數和實例之間沒法直接訪問,須要經過__proto__指針間接讀取。
這個"大閉環"畫出來就是下面這個樣子啦:
到此第一個問題已經解決。
(2)prototype是啥,__proto__又是啥,他們之間啥關係?
在上一個問題中,咱們用到了實例對象的__proto__指針,實際上在JavaScript中大部分類型的值都擁有__proto__屬性,例如:
固然object和function對象也有:
不過也有不存在__proto___屬性的類型,好比:
等等。
然而。只有function對象纔有prototype屬性,其餘任何類型的值都沒有。即便是使用new方法從function構造出的實例對象也沒有prototype屬性。
(object類型的值的prototype輸出undefined)
(咱們改變了test的prototype的值,將其連接到一個函數名爲test的函數,接着,函數類型的值的prototype輸出了一個原型對象)
so,do you understand?
(3)若是改變一個 constructor 的 prototype,他的實例會發生什麼改變?
咱們來作一個嘗試:
咱們能夠發現,改變了prototype以後建立的實例指向了新的prototype對象,而以前的依然指向老的prototype對象。
下面是個應用這個方法拓展實例的小例子:
var shape = function () { }; var p = { a: function () { console.log('aaa'); } }; shape.prototype = p; var circle = new shape(); circle.a(); //輸出'aaa'
好啦,到這裏就講完啦~~撒花哈哈哈哈~~~
本文內容原創,轉載請告知~