JavaScript面向物件的三大特性
1、JavaScript面向物件的三大特性
JavaScript的三大特性:封裝性、繼承性、多型性。
2、JavaScript實現封裝特性
在一些靜態型別的語言如java中,本身語法就提供了這些功能。js當中只能依靠變數的作用域來實現封裝的特性,並且只能模擬出public和private兩種特性。封裝實現就是是物件內部的變化對外界是透明的,不可見。這種做法使物件之間低耦合,便於維護升級,團隊協作開發。
3、JavaScript實現繼承特性
繼承可以解決程式碼複用,讓程式設計更加靠近人類思維。當多個類存在相同的屬性(變數)和方法時,可以從這些類中抽象出父類,在父類中定義這些相同的屬性和方法,所有的子類不需要重新定義這些屬性和方法,只需要通過繼承父類中的屬性和方法。
JS中實現繼承的方式:
1、通過call或者apply實現繼承
1 //1.把子類中共有的屬性和方法抽取出,定義一個父類Stu 2 function Stu(name,age){ 3 //window.alert("確實被呼叫."); 4 this.name=name; 5 this.age=age; 6 this.show=function(){ 7 window.alert(this.name+"年齡是="+this.age); 8 } 9 } 10 //2.通過call或者apply來繼承父類的屬性的方法11 function MidStu(name,age){ 12 //這裡這樣理解: 通過call修改了Stu建構函式的this指向, 13 //讓它指向了呼叫者本身. 14 Stu.call(this,name,age); 15 //如果用apply實現,則可以 16 //Stu.apply(this,[name,age]); //說明傳入的引數是 陣列方式 17 //可以寫MidStu自己的方法. 18 this.pay=function(fee){ 19 window.alert("你的學費是"+fee*0.8); 20 }21 } 22 function Pupil(name,age){ 23 Stu.call(this,name,age);//當我們建立Pupil物件例項,Stu的建構函式會被執行,當執行後,我們Pupil物件就獲取從 Stu封裝的屬性和方法 24 //可以寫Pupil自己的方法. 25 this.pay=function(fee){ 26 window.alert("你的學費是"+fee*0.5); 27 } 28 } 29 //測試 30 var midstu=new MidStu("zs",15); 31 var pupil=new Pupil("ls",12); 32 midstu.show(); 33 midstu.pay(100); 34 pupil.show(); 35 pupil.pay(100);
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <script type="text/javascript"> 11 function Animal(name,age){ 12 this.name=name; 13 this.age=age; 14 this.shout=function(){ 15 alert("我是:"+this.name+",今年:"+this.age); 16 }; 17 this.action=function(){ 18 alert("會吃"); 19 }; 20 } 21 22 function Dog(name,age){ 23 Animal.apply(this, [name,age]); 24 } 25 26 var jack=new Dog("jack",1); 27 alert(jack.name); 28 alert(jack.age); 29 jack.shout(); 30 jack.action(); 31 </script> 32 </body> 33 </html>
2、原型繼承方式實現繼承
原型繼承是js中最通用的繼承方式,不用例項化物件,通過直接定義物件,並被其他物件引用,這樣形成的一種繼承關係,其中引用物件被稱為原型物件。
1 function A(){ 2 this.color = 'red'; 3 } 4 function B(){} 5 function C(){} 6 B.prototype = new A(); 7 C.prototype = new B(); 8 // 測試原型繼承 9 var c = new C(); 10 console.log(c.color); // red
原型繼承顯得很簡單,不需要每次構造都呼叫父類的建構函式,也不需要通過複製屬性的方式就能快速實現繼承。但它也存在一些缺點:
① 每個型別只有一個原型,所以不支援多重繼承(即一個子類繼承自多個父類)。 ② 不能很好的支援多引數或動態引數的父類,顯得不夠靈活。③ 佔用記憶體多,每次繼承都需要例項化一個父類,這樣會存在記憶體佔用過多的問題。
4、JavaScript實現多型特性
JS的函式過載
這個是多型的基礎,JS函式不支援多型,事實上JS函式是無態的,支援任意長度,型別的引數列表。如果同時定義了多個同名函式,則以最後一個函式為準。
1、js不支援過載,通過判斷引數的個數來模擬過載的功能。
1 /*****************說明js不支援過載*****/ 2 function Person(){ 3 this.test1=function (a,b){ 4 window.alert('function (a,b)'); 5 } 6 this.test1=function (a){ 7 window.alert('function (a)'); 8 } 9 } 10 var p1=new Person(); 11 //js中不支援過載. 12 //但是這不會報錯,js會預設是最後同名一個函式,可以看做是後面的把前面的覆蓋了。 13 p1.test1("a","b"); 14 p1.test1("a");
1 //js怎麼實現過載.通過判斷引數的個數來實現過載 2 function Person(){ 3 this.test1=function (){ 4 if(arguments.length==1){ 5 this.show1(arguments[0]); 6 }else if(arguments.length==2){ 7 this.show2(arguments[0],arguments[1]); 8 }else if(arguments.length==3){ 9 this.show3(arguments[0],arguments[1],arguments[2]); 10 } 11 } 12 this.show1=function(a){ 13 window.alert("show1()被呼叫"+a); 14 } 15 this.show2=function(a,b){ 16 window.alert("show2()被呼叫"+"--"+a+"--"+b); 17 } 18 function show3(a,b,c){ 19 window.alert("show3()被呼叫"); 20 } 21 } 22 var p1=new Person(); 23 //js中不支援過載. 24 p1.test1("a","b"); 25 p1.test1("a");
2、多型基本概念
多型是指一個引用(型別)在不同情況下的多種狀態。也可以理解成:多型是指通過指向父類的引用,來呼叫在不同子類中實現的方法。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <script type="text/javascript"> 11 function Animal(){ 12 this.say=function(){ 13 alert("我是動物"); 14 }; 15 } 16 17 function Dog(){ 18 this.say=function(){ //多型的實現需要重寫父類物件的方法 19 alert("我是狗"); 20 }; 21 } 22 Dog.prototype=new Animal();//多型的實現需要原生繼承 23 24 function Cat(){ 25 this.say=function(){ //多型的實現需要重寫父類物件的方法 26 alert("我是貓"); 27 }; 28 } 29 Cat.prototype=new Animal(); 30 31 function say(animal){ 32 if(animal instanceof Animal){ 33 animal.say(); 34 } 35 } 36 37 var dog=new Dog(); 38 var cat=new Cat(); 39 say(dog); 40 say(cat); 41 </script> 42 </body> 43 </html>
備註:多型利於程式碼的維護和擴充套件,當我們需要使用同一類樹上的物件時,只需要傳入不同的引數就行了,而不需要再new 一個物件。