好程式設計師web前端培訓分享Javascript中原型屬性
本文將從以下三個方面講解原型屬性
1 、 理解指標
2 、 理解原型
3 、 用原型的方式完成繼承
以下為詳細內容:
1 、 理解指標
要理解 JAVASCRIPT 中的原型,先理解指標,在 C/C++ 中,會提到指標,其實,指標不應該屬於 C/C++ 的專利,上篇文章中,提到的引用型別 ( 也是很多物件導向語言中的資料型別的叫法 ) ,就是指標。
C/C++ 中對指標的解釋:指標就是地址。地址為何物 ?
地址:是計算機對記憶體每個儲存單元的管理方式。在計算機的記憶體中,儲存著若干資料,計算機的 CPU 是如何讀取記憶體中的資料的 ?
計算機的每個儲存單元都有一個編號,就像到超市存包時,每個存包的格子都有一個編號,這個編號就是地址,記憶體的地址。超市每個格子為什麼要有編號,目的就是為了方便服務員進行查詢 ( 根據編號進行查詢 ) ,計算機每個儲存單元為什麼會有一個編號,目的也是為了 CPU 查詢記憶體。
01
如果某個記憶體中直接儲存的是資料,則這種資料是基本型別的資料,如果某個記憶體中儲存的是其它記憶體的編號 ( 資料 ) ,那麼這種資料就叫引用型別的資料。
2 、 理解原型
a) 原型 ( 屬性 ) 的概念
JAVASCRIPT 中的函式也是物件 ( 如果不懂函式也是個物件,請百度 JAVASCRIPT 中函式是功能完整的類 ) ,每個函式都有一個原型 (prototype) 屬性,這個屬性是指標型別。原型屬性是物件型別,所以,也可以叫原型物件,原型就是模子,模型。函式何來原型,其實理解原型 ( 模型 ) 更應該用建構函式來理解會更好。
建構函式是用來構造例項的,每次用 new 運算子呼叫建構函式產生一個例項時,模型就會起作用。就像我們要造一個塑膠製品 ( 如:杯子,電腦顯示器的外殼,印表機的外殼等 ) ,都有一個模具,只要是同一個模具做出來的物體,都非常相似。所以,百度上對模具的解釋:模具的俗稱。常用於比喻具有大量相似點的兩個或多個人或者事物。
b) 原型模式建立物件 ( 把建構函式和原型模式合在一起 )
用同一個建構函式構造的例項,具有很多的共同點 ( 共同的屬性或者函式 ) ,這些共同點就是很多書籍描述的“所有例項共享的屬性和方法”。這些共同點就是用 prototype 屬性進行維護的。具體的做法就是:所有例項共享的屬性和方法用 prototype 屬性進行表示。
如:
function Person(id,name,sex){
// 在建構函式里寫的是每個例項特有的屬性 ( 屬性值不一樣 )
this.id =id;
this.name = name;
this.sex = sex;
}
// 所有人的國籍都是中國,國籍屬性就用 prototype 來表示
Person.prototype.country = “中國” ;
// 所有人吃的邏輯都一樣。所以,吃的函式也用 prototype 來表示
Person.Prototype.eat = function(str){
alert(this.name+ ”在吃” +str+ ”,天在看……” );
}
var p1 = new Person( “ 007 ” , “樂樂” , “女” );
var p2 = new Person( “ 008 ” , “寶寶” , “男” );
Console.log(p1.country);// 中國
Console.log(p2.country); // 中國
p1 和 p2 兩個例項的 country 屬性值都是中國,因為它們兩個是一個建構函式例項化出來的 ( 一個模子“刻”出來的 ) 。
如下是示意圖,其中帶箭頭的線表示指向。
02
圖中可以看出:
1) 、在 Person 建構函式的 prototype 屬性中有個 constructor 屬性,指向了建構函式本身。 constructor 屬性到底有何用,大家先把它 save 到大腦中,後面給大家講解。
2) 、兩個例項 p1 和 p2 指向了 Person 建構函式的 prototype 屬性,跟 Person 建構函式沒有直接關係。
3) 、兩個例項 p1 和 p2 都有 [[prototype]] 屬性。例項靠著 [[prototype]] 屬性找到它所對應建構函式的原型,也是靠它來找到,原型中的屬性的。注意, [[prototype]] 屬性不能直接在程式碼中使用。
c) 原型 ( 型別的 ) 屬性和例項 ( 型別的 ) 屬性
每個例項特有的屬性和方法存放在例項所在記憶體區域,也叫例項屬性,如以上例中的 id , name , sex 屬性。所有例項共享的屬性和方法,都在原型 (prototype) 對應的記憶體區域,也叫原型的屬性,如上例中的 country 。
i. 原型 ( 型別的 ) 屬性變成例項 ( 型別的 ) 屬性
這裡有點疑惑,隨著時間的推移,有的物件的原型屬性的值會發生變化 ?
如:寶寶年輕時,覺得俄羅斯的美女多,決定定居俄羅斯了。即 p2 的 country( 國籍 ) 的值為俄羅斯。那該如何是好,改還是不改 ? 改了會不會影響其它物件的 country 屬性的值。不改,又不能滿足需求。看來, JAVASCRIPT 在這方面還是考慮到了。可以改,而且不會影響其它物件的屬性值。
還有,如果出現了例項屬性和原型屬性重名的情況,用例項來訪問該屬性時,到底訪問的是例項屬性還是原型屬性。這個 JAVASCRIPT 中解決了。
如何解決上面的問題的。在 JAVASCRIPT 中,當給原型屬性賦值時,在對應例項中會增加了一個同名的例項屬性,然後把值賦給例項屬性,而原型屬性的值不受影響。當訪問該屬性時,先在例項屬性中尋找,如果找不到,再在原型屬性中找。
如以下程式碼:
P2.country = “俄羅斯” ;
執行時,記憶體會變成如下:
03
在 p2 的例項中增加一個 country 例項屬性,內容為“俄羅斯” ( 圖中紅色的框裡 ) 。這樣,程式碼 p1.country 依然去找例項屬性的值“中國”。而 p2.country 先在例項屬性中找 country ,找到了,就不用去原型屬性中去找了。即,當例項訪問屬性時,會先在例項的記憶體中去尋找,如果找不到就會到原型的記憶體中去尋找。
ii. 刪除例項 ( 型別的 ) 屬性
隨著寶寶年齡的增長,對美女沒有了興趣,而且覺得還是在自己的國家好,又想回來。即 p2.country 的值為”中國”,這時候是可以利用原型裡的屬性值,怎麼辦 ? 沒事,使用 delete p2.country 就會把 p2 的例項屬性 country 刪除掉。
放心吧, delete 是不能刪除掉原型的屬性的。
3 、 繼承時原型的理解 ( 原型鏈 )
原型鏈是 ECMAScript 中實現繼承的一種方式。如果不懂繼承,請先百度,理解繼承的概念。
原型繼承的基本思想是讓原型屬性 ( 物件 ) 指向另外一個型別的的例項。
如:
父物件:人
function Person(id,name,age){
this.id = id;
this.name = name;
this.age = age;
}
Person.prototype.eat = function(str){
alert(this.name+" 在吃 "+str);
}
子物件:程式設計師
function Programmer(languages){
this.languages = languages;
}
// 此句話使用原型實現了繼承,子物件 Programmer 的原型屬性指向了父物件 Person 的例項。
Programmer.prototype = new Person( “ 008 ” , “寶寶” , “ 20 ” );
Programmer.prototype.writeCode=function(){
alert(this.name+" 一邊努力地寫著程式碼,一邊想著‘多寫程式碼,多掙錢’ ");
}
從圖中可以看出,子物件 Programmer 擁有了父物件的屬性 (id , name , age) 和方法 (eat) 。自己特有的屬性 languages 和方法 writeCode() 。成功完成了繼承。
特別要注意,子物件完成了繼承關係後,再給子物件的原型中增加屬性和方法。即,先寫程式碼 Programmer.prototype = new Person( “ 008 ” , “寶寶” , “ 20 ” ); 再寫程式碼:
Programmer.prototype.writeCode=function(){
alert(this.name+" 一邊努力地寫著程式碼,一邊想著‘多寫程式碼,多掙錢’ ");
}
否則,當子物件的 prototype( 原型 ) 屬性的指向發生變化後,原來在 prototype( 原型 ) 屬性中所寫屬性和方法就會丟失。
原型鏈繼承:當 B 物件的原型屬性指向了 A 物件的例項,而 C 物件的原型屬性指向 B 物件的例項時,就完成了原型鏈繼承。
注:
1 、此篇文章可以結合 JAVASCRIPT 中建立物件的幾種方式進行學習。如果再能結合上篇文章《對比引用型別與基本型別》就會更好
2 、此篇文章只是為了理解 prototype 屬性,所以,很多的注意點並沒有涉及。作者更希望大家學一點,理解一點,而不是大而全。而且學習是循序漸進的。先把 prototype 屬性理解了,再去關注注意點。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2639991/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師web前端培訓分享JavaScript框架J程式設計師Web前端JavaScript框架
- 好程式設計師web前端培訓分享學習JavaScript程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習指南程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享九個JavaScript小技巧程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript基礎語法程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript相關知識程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習筆記Promise程式設計師Web前端JavaScript筆記Promise
- 好程式設計師web前端培訓分享JavaScript學習筆記SASS程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記cookie程式設計師Web前端JavaScript筆記Cookie
- 好程式設計師web前端培訓分享Vue面試題程式設計師Web前端Vue面試題
- 好程式設計師web前端培訓分享怎樣學好css?程式設計師Web前端CSS
- 好程式設計師web前端培訓分享JavaScript學習筆記之設計模式程式設計師Web前端JavaScript筆記設計模式
- 好程式設計師Web前端培訓分享jQuery面試題梳理程式設計師Web前端jQuery面試題
- 好程式設計師web前端培訓分享HTML DOM節點程式設計師Web前端HTML
- 好程式設計師web前端培訓分享HTML DOM簡介程式設計師Web前端HTML
- 好程式設計師web前端培訓分享CSS定位的教程程式設計師Web前端CSS
- 好程式設計師web前端培訓分享如何講清楚Promise?程式設計師Web前端Promise
- 好程式設計師Web前端培訓分享如何講清楚this指向?程式設計師Web前端
- 好程式設計師web前端培訓分享JavaScript學習筆記分支結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆陣列的排序程式設計師Web前端JavaScript陣列排序
- 好程式設計師web前端培訓分享JavaScript學習筆記之陣列程式設計師Web前端JavaScript筆記陣列
- 好程式設計師web前端培訓分享JavaScript學習筆記之正則程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享Vue面試題1.程式設計師Web前端Vue面試題
- 好程式設計師web前端培訓分享node學習筆記程式設計師Web前端筆記
- 好程式設計師web前端培訓分享FormData 簡單介紹程式設計師Web前端ORM
- 好程式設計師web前端培訓分享HTML/CSS部分面試題程式設計師Web前端HTMLCSS面試題
- 好程式設計師web前端培訓JavaScript學習筆記DOM程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓JavaScript學習筆記--jQuery程式設計師Web前端JavaScript筆記jQuery
- 好程式設計師web前端培訓分享JavaScript學習筆記函式進階程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享JavaScript學習筆記之ES5程式設計師Web前端JavaScript筆記
- 好程式設計師web前端分享css常用屬性縮寫程式設計師Web前端CSS
- 好程式設計師web前端培訓分享kbone高階-事件系統程式設計師Web前端事件
- 好程式設計師web前端培訓分享HTMLCSS學習筆記BFC程式設計師Web前端HTMLCSS筆記
- 好程式設計師web前端培訓分享JS面試題總結一程式設計師Web前端JS面試題
- 好程式設計師web前端培訓分享React學習筆記(一)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享React學習筆記(二)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享React學習筆記(三)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記之迴圈結構程式設計師Web前端JavaScript筆記