Javascript之旅——第十一站:原型也不好理解?


  寫到這篇,我的js系列也快接近尾聲了,所以這個系列不會遺留js來實現面向對象的核心——原型,有些人說原型不好理解,其實嘛,要想系統

的理解原型,最便捷的方式就是看看經典的書,少看些博客,博客這東西只是博主自己的個人理解,充其量是些配味的佐料。

 

一:繼承

如果你熟悉C#的話,你肯定會知道,所有的類都是繼承於Object的,這樣我就擁有Object所具有的功能了,如下圖中我定義的Person類。

從圖中可以看到,在C#中到處都是繼承,下一步我要做的就是自定義繼承,如下圖中我定義的Student類,讓它繼承Person.Name屬性。

這些對於玩C#的人來說都是很司通見慣的,那么下一個問題來了,這些真正的面向對象的東西,在js中該怎么玩呢?當然就要用到大名鼎鼎的

prototype屬性了。

 

二:用JS來模仿C#的繼承

1.默認繼承Object

 我們都知道在js中的所有引用類型也同樣繼承於Object,這樣也就具有Object的功能了,但是你有沒有考慮過,比如下圖中的Person到底是怎么繼承

了Object的所有屬性和方法呢?

看到上圖后,你是不是很好奇呢?其實原理真的很簡單,用chorme的watch expressions一看你就一清二楚了。

第一眼看到不知道你會不會眼暈?聽我慢慢解釋,從上面的圖中不難看到,其實有這么個原型鏈的關系:

p.__proto__ =Person.prototype

Person.prototype.__proto__ -> new Object()

不知道你看懂了沒?其實這里最重要的就是__proto__屬性,首先你要知道,每個實例都具有這么個__proto__屬性,因為這是核心,比如你要找

p.toString()方法, js引擎會優先在Person function中找toString()方法,發現沒有。。。花擦。。。沒轍只能通過p.__proto__屬性繼續往上

查找,到了Person.prototype,從圖中可以看到prototype是一個具有constructor屬性的對象,因為只有一個屬性,所以也沒找到tostirng()方法,

然后沿着Person.prototype._proto__找到了Object,在這里我們就找到了toString()方法。

 

2.自定義繼承

我們知道prototype是個非常重要的屬性,為了模仿C#中Student類繼承於Person類,這次我需要做的是讓Studnet.prototype=new Person()就好了。

從圖中可以看到student實例已經含有Name屬性了,我們現在已經知道有一個原型鏈查找的過程,比如我現在通過student.__proto__找到了new Person(),

然后也看到了new Person()具有Name屬性,我想你現在也知道,在Person函數中也有一個__proto__屬性,它是指向Object的,如果說我在new Person()

中沒有找到,那么會繼續通過Person.__proto__(Student.prototype.proto__)繼續往上找,一直找到頂端為止。

 

三:詳解prototype

1. prototype到底是什么?

從上一章中我想你對prototype應該有了宏觀了解,可以看到其實prototype只不過是一個包含constructor屬性的Object對象,其中constructor屬性是指

向當前function的一個指針,代碼還原如下:

 1 <script type="text/javascript">
 2         function Person() {
 3             this.Name = "ctrip";
 4         }
 5 
 6         Person.prototype = {
 7             constructor: Person  //指向Person的constructor
 8         };
 9 
10         var p = new Person();
11     </script>

2. prototype上面的屬性可以被所有實例共享。

  這個之所以能夠共享,是因為每個實例都有__proto__屬性,包括function的prototype屬性也是有__proto__屬性的,這是因為prototype本質上

也是一個對象的實例,所以js在查找某個屬性是否存在的時候會通過__proto__屬性一直追蹤到object。

 

3. 如果function中的屬性與prototype屬性沖突了怎么辦?

看到答案后,我想你也非常清楚了,畢竟你已經理解了原型鏈的查找,因為js引擎查找過程是先從本函數查找,如果找到就return,找不到繼續通過

__proto__往上找,很好理解的。


免責聲明!

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



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