Javascript 原型鏈之原型對象、實例和構造函數三者之間的關系


前言:用了這么久js,對於它的原型鏈一直有種模糊的不確切感,很不爽,隧解析之。

本文主要解決的問題有以下三個:

(1)constructor 和 prototype 以及實例之間啥關系?

(2)prototype是啥,__proto__又是啥,他們之間啥關系?

(3)如果改變一個 constructor 的 prototype,他的實例會發生什么改變?

ok,下面一個一個解決。

 

(1)constructor 和 prototype 以及實例對象三者之間啥關系?

舉例:

  如上,當我們創建一個函數,系統就會為這個函數自動分配一個prototype指針,指向它的原型對象。並且可以發現,這個原型對象包含兩個部分(constructor 和 __proto__)其中constructor指向函數自身。(這里形成了一個小閉環)

  當我們將該函數作為模版創建實例(new方法)的時候,我們發現創建出的實例是一個與構造函數同名的object,這個object是獨立的,他只包含了一個__proto__指針(實例沒有prototype,強行訪問則會輸出undefined),這個指針指向上面提到的構造函數的prototype原型對象。

  這時候我們發現三者形成了一個大"閉環"。之所以加上引號,因為構造函數和實例之間無法直接訪問,需要通過__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'

 

好啦,到這里就講完啦~~撒花哈哈哈哈~~~

 

本文內容原創,轉載請告知~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM