js 原型與原型鏈


前言

什么是原型?

原型,漢語詞語,讀音為yuán xíng。指原來的類型或模型,特指文學藝術作品中塑造人物形象所依據的現實生活中的人。

狹義上將是原型人物。通常這樣的解釋,往往我們會覺得原型與產品之間,是在原型上破壞性的加工。

如果這樣理解的話,那么將會對js的原型理解艱難,因為英文翻譯過來是抽象的。

js的原型是擴展的意思,就像我們學數據結構的雙向鏈表一樣。

也就是說原型是擴展的對象的一個屬性。

那么什么是原型鏈?

原型鏈指的是指向原型的這條連接,直到指向null為指,因為這個時候鏈接就斷了。

好的概念理解完了,開始正文吧。下面理解,均為個人理解,如有不對望指出。

正文

上面寫道擴展對象的一個屬性指向了原型,那么這個屬性是什么?

是__proto__。

proto 與 prototype

看一段代碼:

var obj= new Object();
consoleProto(obj);
function consoleProto(obj){
	  if(obj!=null)
	  {
		console.log(obj.__proto__);
		consoleProto(obj.__proto__);
	  }
}

上文我通過遞歸的方式,把原型鏈打印了出來。

也就是說我創建一個對象,都會有一個屬性__proto__指向另外一個對象。

現在我不關心null,我更關心的是紅框中的對象到底是啥?

接來下我寫了另一段代碼:

var obj= new Object();
var obj2=new Object();
console.log(obj.__proto__===obj2.__proto__);

返回的結果為:true。

這個說明什么呢?說明任何一個對象的原型最終會基於一個公共原型對象。

也就是說new Object() 會把一個新的對象增加一個公共的對象引用。

那么new Object()是如何獲取這個對象的呢?調用了什么函數可以獲取到這個對象?或者說Object本身就帶有這個公共屬性?

我寫下了另外一段代碼:

<script>
var obj= new Object();
console.log(Object.prototype===obj.__proto__);
</script>

結果為true。

原來Obect本身就帶有這個屬性。

那么再往上推,Object是什么,Object是一個函數。

把Object 打印出來,然后提出疑問是否每個函數都具有prototype 屬性?

function Object1(){
}
console.log(prototype);

console.log(Object1.prototype==Object.prototype);

打印出來是prototype 有值,后面的結果為false。

證明了每個函數,都具有prototype,但是Object比較特殊,其Object內置函數。

他們的關系如下:

console.log(Object1.prototype.__proto__==Object.prototype);

那么現在單獨討論Object1,Object1是一個函數但是同時也是一個對象,那么從對象的角度來看下,對象想到的是__proto__.

function Object1(){

}
console.log(Object1.__proto__==Function.prototype);

得出的結果為true。

如圖:

那么上圖中的原型對象是否就是原始對象。有兩種方法可以證明一種就是沒有原型,一種就是和原始對象做對比。

console.log(Object1.__proto__==Object.prototype);

我采用第二種,結果不是。同時說明Fuction 不是 Object的構造函數。

實際上是這樣的:

console.log(Function.prototype==Function.prototype);
console.log(Function.prototype.__proto__==Object.prototype);

兩者都為true。

上述結論圖:

其中內置方法沒有prototype,所以不是每個函數都有prototype。

再次__proto__ 與 prototype

上述提及的是內部的對象關系,那么我們書寫的時候不用理會這么多了。

function Tree(){
}

var newtree=new Tree();

console.log(newtree.__proto__==Tree.prototype);

關系為:

constructor

既然構造函數能夠知道原型,原型是否能夠知道構造函數,也是可以的。

console.log(Tree==Tree.prototype.constructor);

兩者相生相伴,一起出生。

為什么說原型鏈可以實現繼承?

function Tree(){

}

Tree.prototype.name="白楊樹";

var newtree=new Tree();

console.log(newtree.name);

這時候打印出來的是“白楊樹“。也就是說如果newtree找不到,則會去根據原型鏈找原型,一直找下去,知道找到為止。

同樣:

console.log(newtree.contructor==Person);

也就是因為newtree沒有這個屬性,只好找原型了。

最后一筆

console.log(Tree.prototype.__proto__.constructor);

修改一下:

總結

以上皆為個人理解,如有不對,望請指點。


免責聲明!

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



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