一、澄清概念
1.JS中"基於對象=面向對象"
2.JS中沒有類(Class),但是它取了一個新的名字叫“原型對象”,因此"類=原型對象"
二、類(原型對象)和對象(實例)的區別與聯系
1.類(原型對象)是抽象,是概念的,代表一類事物。
2.對象是具體的,實際的,代表一個具體的事物。
3.類(原型對象)是對象實例的模板,對象實例是類的一個個體。
三、抽象的定義
在定義一個類時,實際上就是把一類事物的共有屬性和行為提取出來,形成一個物理模型(模板),這種研究問題的方法稱為抽象。
四、JavaScript面向對象三大特征
4.1.封裝
封裝就是把抽象出來的屬性和對屬性的操作封裝在一起,屬性被保護在內部,程序的其它部分只有通過被授權的操作(函數),才能對屬性進行操作!
封裝的范例:
1 <script type="text/javascript"> 2 /*定義一個Person類*/ 3 function Person(_name,_age,_salary){ 4 //Person類的公開屬性,類的公開屬性的定義方式是:”this.屬性名“ 5 this.Name=_name; 6 //Person類的私有屬性,類的私有屬性的定義方式是:”var 屬性名“ 7 var Age=_age; 8 var Salary=_salary; 9 10 //定義Person類的公開方法(特權方法),類的公開方法的定義方式是:”this.functionName=function(){.....}“ 11 this.Show=function(){ 12 alert("Age="+Age+"\t"+"Salary="+Salary);//在公開方法里面訪問類的私有屬性是允許的 13 } 14 /* 15 定義Person類的私有方法(內部方法), 16 類的私有方法的定義方式是:”function functionName(){.....}“, 17 或者 var functionName=function(){....} 18 */ 19 function privateFn(){ 20 alert("我是Person類的私有函數privateFn"); 21 } 22 23 var privateFn2=function(){ 24 alert("我是Person類的私有函數privateFn2"); 25 } 26 } 27 /*通過prototype給可以類的所有對象添加公共(public)方法, 28 但是這種方式定義的方法不能去訪問類的私有屬性和私有方法*/ 29 Person.prototype.Fn=function(){ 30 alert("訪問公共屬性this.Name="+this.Name);//訪問公共屬性,OK的 31 //alert("訪問私有屬性Aag="+Age);//訪問私有屬性,這里會報錯“Age未定義” 32 //privateFn();//調用私有方法,這里會報錯“缺少對象” 33 34 } 35 36 var p1 = new Person("孤傲蒼狼",24,2300); 37 alert("p1.Name="+p1.Name);//訪問公有屬性,這是可以正常訪問的 38 alert("p1.Age="+p1.Age+"\t"+"p1.Salary="+p1.Salary);//不能使用類的對象去直接訪問類私有屬性,這是訪問不了的,結果都是undefined 39 p1.Show();//調用類的公共函數,這次允許的 40 p1.Fn();//調用類的公共函數,這次允許的 41 //alert("p1.privateFn():"+p1.privateFn()+" p1.privateFn2():"+p1.privateFn2());//不能使用類的對象去調用類的私有方法,這里會報錯”對象不支持此屬性或者方法“ 42 </script>
4.2.繼承
繼承范例:
1 <script type="text/javascript"> 2 /*定義Stu類*/ 3 function Stu(name,age){ 4 this.Name=name; 5 this.Age=age; 6 this.Show=function(){ 7 window.alert("我的名字是:"+this.Name+",今年:"+this.Age); 8 } 9 this.SayHello = function(){ 10 window.alert("Hello,"+this.Name); 11 } 12 } 13 14 /*定義MidStu類*/ 15 function MidStu(name,age){ 16 this.stu=Stu;//MidStu類繼承Stu類 17 this.stu(name,age);//JS中實際上是通過對象冒充來實現繼承的,這句話不能少,因為JS是動態語言,如果不執行,則不能實現繼承效果 18 /* 19 從父類繼承下來的公共方法,可以根據實際情況選擇重寫 20 */ 21 //在子類MidStu中重寫父類Stu的Show方法 22 /*this.Show=function(){ 23 alert("MidStu.Show()"); 24 }*/ 25 //在子類MidStu中重寫父類Stu的SayHello方法 26 this.SayHello=function(){ 27 alert("你好,"+this.Name); 28 } 29 30 } 31 32 var midStu = new MidStu("孤傲蒼狼",24);//創建一個MidStu類實例對象 33 alert("訪問繼承下來的屬性Name和Age,midStu.Name="+midStu.Name+",midStu.Name="+midStu.Age);//訪問繼承下來的屬性 34 midStu.Show();//調用從父類Stu繼承下來的Show方法 35 midStu.SayHello();//調用從父類Stu繼承下來的SayHello方法,SayHello()在子類中進行了重寫,這里調用的是重寫過后的SayHello()方法 36 </script>
運行結果:
4.3.多態
所謂多態,就是指一個引用在不同情況下的多種狀態,在Java中多態是指通過指向父類的引用,來調用不同子類中實現的方法。
JS實際上是無態的,是一種動態語言,一個變量的類型是在運行過程中由JS引擎決定的,所以說,JS天然支持多態。
五、JavaScript自定義類(原型對象)的方式
5.1.工廠方法——使用new Object創建對象並添加相關屬性
1 //通過Object直接創建對象 2 //var p1 = new Object();//創建一個Object對象 3 var p1 = {};//創建一個Object對象,簡寫 4 //動態增加屬性、方法 5 p1.Name = "孤傲蒼狼"; 6 p1.Age = 24; 7 p1.SayHello = function() { alert("hello,"+p1.Name); }; 8 p1.SayHello(); 9 for(var propertyName in p1) {//對象的成員都是對象的key 10 alert(propertyName); 11 }
5.2.使用構造函數來定義類(原型對象)
基本語法:
1 function 類名(){ 2 this.屬性名;//公共屬性 3 var 屬性名;//私有屬性 4 /*凡是定義類的公共屬性和公共方法都要使用this*/ 5 //定義類的公共函數 6 this.函數名=function(){ 7 8 } 9 //定義類的私有函數 10 function 函數名(){ 11 12 } 13 }
范例:
1 /*定義一個貓類,這種就是使用構造函數來定義類(原型對象)*/ 2 function Cat(){ 3 this.Name="catName";//public屬性 4 this.Age;//public屬性 5 this.Color;//public屬性 6 var weight=2;//private屬性,只能在Cat類內部使用,Cat類的對象無法訪問這個私有屬性 7 //public方法 8 this.publicFunction = function(){ 9 alert(weight); 10 alert("貓叫..."); 11 } 12 //private方法,只能在Cat類內部使用,Cat類的對象無法訪問這個私有方法 13 var privateFunction = function(){ 14 alert("私有方法"); 15 } 16 17 18 } 19 //如果這樣用,那么就當成函數來使用 20 Cat(); 21 //如果這樣用,那么就當成類來使用 22 var cat1 = new Cat(); 23 //cat1就是一個對象(實例) 24 alert(cat1.Name);//訪問公共屬性,彈出默認值catName 25 cat1.Name="TomCat";//訪問公共屬性 26 cat1.Age=3;//訪問公共屬性 27 cat1.Color="白色";//訪問公共屬性 28 alert(cat1.weight);//訪問私有屬性,無法訪問,彈出undefined 29 alert(cat1.Name+"\t"+cat1.Age+"\t"+cat1.Color);//訪問對象的屬性方式1:對象名.屬性名 30 alert(cat1["Name"]+"\t"+cat1["Age"]+"\t"+cat1["Color"]);//訪問對象的屬性方式2:對象名["屬性名"] 31 cat1.publicFunction();//調用public方法 32 cat1.privateFunction();//調用private方法,報錯:對象不支持此屬性或方法 33 for(var property in cat1){ 34 document.writeln(property+"\t"); 35 }
JS中一切都是對象,類(原型對象)其實也是對象,它實際上是Function類的一個實例
1 document.write("<pre>"); 2 function Person(){ 3 4 } 5 /*Person.constructor得到的Person類的構造函數如下: 6 function Function() { 7 [native code] 8 } 9 */ 10 document.writeln("Person.constructor:"+Person.constructor);//Person類的構造函數 11 document.writeln("Person:"+Person); 12 var p1 = new Person(); 13 document.writeln("p1.constructor:"+p1.constructor);//”p1.constructor“是得到p1實例的構造函數 14 //如何判斷某個對象是不是某個類型,采用如下兩種方式 15 if(p1 instanceof Person){ 16 document.writeln("p1 is Person ok1"); 17 } 18 if(p1.constructor==Person){ 19 document.writeln("p1 is Person ok2"); 20 } 21 22 var num1=123; 23 document.writeln("num1.constructor:"+num1.constructor); 24 25 var str1="abc"; 26 document.writeln("str1.constructor:"+str1.constructor); 27 document.write("</pre>")
運行結果:
Person.constructor:
function Function() {
[native code]
}
Person:function Person(){
}
p1.constructor:function Person(){
}
p1 is Person ok1
p1 is Person ok2
num1.constructor:
function Number() {
[native code]
}
str1.constructor:
function String() {
[native code]
}
