JavaScript學習3:原型和繼承
原型
我們建立的每一個函式都有一個prototype(原型)屬性,這個屬性是一個物件,它的用途是包含可以由特定型別的所有例項共享的屬性和方法。邏輯上可以這麼理解:prototype是通過呼叫建構函式而建立的那個物件的原型物件。
為什麼要引入原型的概念呢?使用原型的目的,也是他的好處是可以讓所有的物件例項共享它所包含的屬性和方法。換句話說,就是不必再建構函式中定義物件資訊,而是可以直接將這些資訊新增到原型中。
具體怎麼用,我們來看程式碼例項:
<span style="font-size:18px;">//原型例項
function Person(){} //宣告一個建構函式
Person.prototype.name='Lian'; //在原型裡新增屬性
Person.prototype.age=100;
Person.prototype.run=function(){ //在原型裡新增方法
return this.name + this.age + '奮鬥中……';
};
var person1=new Person();
var person2=new Person();
alert(person1.run==person2.run); //返回true,說明方法的引用地址是一致的,即兩個物件共享了一個方法</span>
為了更好的理解建構函式的宣告方式和原型模式的宣告方式的區別,我找了兩張圖分享給大家,幫助大家理解:
我們從圖中可以看到,在原型模式宣告中,多了兩個屬性,這兩個屬性都是建立物件時自動生成的。_proto_屬性是例項指向原型物件的一個指標,它的作用就是指向建構函式的原型屬性constructor。通過這兩個屬性,就可以訪問到原型裡的屬相和方法了。
看到這裡你會覺得奇怪,上面程式碼例項中的建構函式的函式體中什麼也沒有,才能訪問到原型物件裡的值,如果函式體中有屬性或者方法呢?這裡就要涉及一個原型模式執行流程的問題了:是先去查詢建構函式例項裡面的屬性和方法,如果有,立刻返回,若沒有,則去它的原型物件中找,若有,則返回。
使用原型模式建立物件也有其缺點,那就是它省略了建構函式傳參初始化這一過程,帶來的缺點就是初始化的值都是一樣的,但是這恰恰是它最大的優點,那就是共享。
繼承
繼承是物件導向中的一個核心概念,在比較正統的物件導向的語言中一般都會採用兩種方式實現繼承:一個是介面實現,一個是類繼承。而我們的JavaScript只支援繼承,而不支援介面實現,繼承是如何實現的,這裡要引入原型鏈的概念了。什麼是原形鏈,我們看一段程式碼就會知道。
<span style="font-size:18px;">//繼承例項
function A(){
this.name ='Lian';
}
function B(){
this.age=100;
}
function C(){
this.address='中國';
}
B.prototype.age =200;
B.prototype =new A(); //B繼承了A
C.prototype =new B(); //C又繼承了B
var c=new C();
alert(c.name+' '+ c.age); //C具有了A和B的屬性</span>
在JavaScript中,被繼承的函式稱為超型別(也就是物件導向中說的父類或者說是基類),繼承的函式稱為子型別(即子類或者派生類)。繼承有好處,但是也有其自己的問題,比如字面量重寫原型會中斷關係,使用引用型別的原型,並且子型別無法給超型別傳遞引數。
綜合考慮,我們使用原形鏈加上建構函式,這樣產生了組合繼承。
<span style="font-size:18px;">//組合繼承
function Box(age){
this.name='Lee';
this.age=age;
}
Box.prototype.run=function(){
return this.name +this.age;
};
function Desk(age ){
Box.call(this,age); //物件冒充,給超型別傳參
}
Desk.prototype =new Box(); //原形鏈繼承
var desk =new Desk(100);
alert (desk.run()); //顯然Desk繼承了Box的run方法</span>
組合繼承是JavaScript最常用的繼承方式,但是,組合繼承也有一點問題,那就是超型別在使用過程中會被呼叫兩次,一次是建立子型別的時候,一次是在子型別建構函式的內部。這樣會帶來效能上的開銷,如何解決?留給讀者去思考……
相關文章
- JavaScript原型和繼承JavaScript原型繼承
- javascript的原型和繼承JavaScript原型繼承
- JavaScript中的原型和繼承JavaScript原型繼承
- JavaScript 型別、原型與繼承學習筆記JavaScript型別原型繼承筆記
- 白話JavaScript原型鏈和繼承JavaScript原型繼承
- 征服 JavaScript 面試:類繼承和原型繼承的區別JavaScript面試繼承原型
- 原型,繼承——原型繼承原型繼承
- 原型和繼承原型繼承
- 從本質認識JavaScript的原型繼承和類繼承JavaScript原型繼承
- javascript原型鏈及繼承JavaScript原型繼承
- javascript - 繼承與原型鏈JavaScript繼承原型
- JavaScript物件導向 ~ 原型和繼承(1)JavaScript物件原型繼承
- 【面試必備】javascript的原型和繼承面試JavaScript原型繼承
- Javascript繼承4:潔淨的繼承者—-原型式繼承JavaScript繼承原型
- JavaScript 學習之繼承JavaScript繼承
- JS原型繼承和類式繼承JS原型繼承
- 【機制】JavaScript的原型、原型鏈、繼承JavaScript原型繼承
- 深入淺出JavaScript之原型鏈和繼承JavaScript原型繼承
- 圖解JavaScript原型鏈繼承圖解JavaScript原型繼承
- javascript原型鏈繼承的使用JavaScript原型繼承
- Javascript之繼承(原型鏈方式)JavaScript繼承原型
- 深入理解javascript原型和閉包(6)——繼承JavaScript原型繼承
- javascript基礎-原型鏈與繼承JavaScript原型繼承
- JavaScript原型與繼承的祕密JavaScript原型繼承
- 【翻譯】JavaScript原型繼承工作原理JavaScript原型繼承
- [JavaScript]原型、原型鏈、建構函式與繼承JavaScript原型函式繼承
- 徹底搞懂原型、原型鏈和繼承原型繼承
- 面試題之原型、原型鏈、和繼承面試題原型繼承
- JS的原型鏈和繼承JS原型繼承
- 說清楚javascript物件導向、原型、繼承JavaScript物件原型繼承
- 深入理解JavaScript原型鏈與繼承JavaScript原型繼承
- 深入淺出JavaScript之原型鏈&繼承JavaScript原型繼承
- 一次掌握 JavaScript 原型與繼承JavaScript原型繼承
- 物件-原型-繼承物件原型繼承
- Javascript 繼承和克隆JavaScript繼承
- 深入理解原型鏈和繼承原型繼承
- JS原型鏈繼承JS原型繼承
- 原型繼承:子類原型繼承