---->什麼是類和對象
這是所有物件導向編程之前必須弄明白的.
所謂類:簡單地說就是模板,說的專業一些,是一類具有某種性質的物的集合.比如:人就是一個類,車也是一個類,等等.
所謂對象:就是類的具體實現.如上面所說,人是一個類,一個具體的人就是一個對象,比如張三.
對象是類的執行個體化後的結果.javascript中使用new關鍵字來執行個體化一個類,產生一個對象.
例子:
function people(){ //javascript中一個function也是一個類,這裡我們建立一個空的類people
}
var zhangsan=new people; //執行個體化產生一個對象張三
---->一個具體形象的例子
/*-->最簡單的類:
*people類
* 屬性:性別,年齡,姓名
* 方法:說話
*/
function people(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age;
this.say=function(){
return "我叫"+this.name;
}
}
使用時:
var zhangsan=new people;
alert(zhangsan.say());
var lisi=new people;
alert(lizi.say());
說明:
上面使用了this關鍵字,this總是指向當前的對象,在上面例子中,zhangsan.say中具有this.name,這裡的this是當前的對象zhangsan.後面lisi.say則是指向當前對象lisi
對象具有屬性,上面的name,sex和age就是對象的屬性.我們這樣可以訪問,如lisi.name,zhangsan.age
對象還具有方法,比如上面的say.方法是通過建構函式實現的.使用時,如上面,用lisi.say(),zhangsan.say()
當然我們還可以在執行個體化對象後為對象添加新的屬性和方法.比如:
zhangsan.girlfriend="小麗";
zhangsan.doing=function(){
return "I am eating";
}
---->javascript類/對象和其他物件導向語言的異同
相同點:物件導向編程的思想都是一樣的,世界上所有的具體事物都可以看成對象,而這些事物從屬的集合都可以看成類.我們要做的是構造我們需要的類,在執行個體化成我們需要的對象為我們工作.
不同點:其他物件導向編程的語言對於類/對象關心下面的事情:
1.範圍:公用,私用,受保護,靜態.而javascript只有一種範圍:公用範圍.
2.特性:繼承,多態.javascript不支援多態,繼承方面的內容將在"javascript對象的繼承"一文中介紹
---->構建javascript類/對象的方式
首先,可以大致定義出下面幾種類型:
1.工廠方式
2.建構函式方式
3.原型方式
4.混合的建構函式/原型方式
5.動態原型方法
6.混合工廠方式
具體說明:
A.工廠方式:
所謂工廠方式,是指先建立對象,然後再往對象裡面添加屬性和方法.
eg.1
var zhangsan=new Object; //建立對象
zhangsan.name="張三"; //給對象添加屬性
zhangsan.say=function(){ //給對象增加方法
alert("我叫張三");
}
eg.2 上面的例子沒有封裝性,我們可以使用函數封裝,實現多重利用
function people(){
var p_object=new Object;
p_object.name="張三";
p_object.say=function(){
alert("我叫張三");
}
return p_object; //返回對象
}
var zhangsan=people;
var lisi=people;
上面zhangsan和lisi兩個對象具有完全相同的屬性和方法,都叫"張三"(name屬性),都會說"我叫張三"(say()方法)
eg.3 通過傳遞參數改進eg.2
function people(name){
var p_object=new Object;
p_object.name=name;
p_object.say=function(){
alert("我叫"+this.name);
}
return p_object; //返回對象
}
var zhangsan=people("張三");
var lisi=people("李四");
總結:
工廠方式,總是先建立一個對象,再往對象中添加你需要的屬性和方法.但這種做法對於封裝性和多種利用性不是很有利,這導致了這種對象的構造方法不被提倡.
使用工廠方式總是為每個對象建立獨立的函數版本.
這類方式使用封裝然後調用新對象的時候不使用new建立對象.
B.建構函式方式:
所謂建構函式方式,就像我給出的例子"一個具體形象的例子",就是採用建構函式的方式.它和工廠方式的區別是不再在函數內部建立一個對象.而是通過this關鍵字指向當前對象.
建構函式的例子不再給出.
建構函式和工廠方式一樣,會重複產生函數,為每個版本的對象建立獨立的函數版本.
C.原型方式
所謂原型方式,就是利用prototype屬性來實現屬性和方法的繼承
eg.1
function people(){
}
people.prototype.name="張三";
people.prototype.say=function(){
alert("我叫"+this.name);
};
var zhangsan=new people();
var lisi=new people();
原型方式不能通過建構函式傳遞參數初始化屬性的值,因為所有的屬性和方法都是通過prototype添加的
D.混合的建構函式/原型方式
對於對象的屬性,使用建構函式的方式
對於對象的方法,使用原型方式
eg.1
function people(name){
this.name=name;
}
people.prototype.say=function(){
return "我的名字叫"+this.name;
};
var zhangsan=new people("張三");
document.write(zhangsan.say());
eg.2 我們也可以把prototype寫入類,實現視覺上的封裝.
function people(name){
this.name=name;
people.prototype.say=function(){
return "我的名字叫"+this.name;
};
}
var zhangsan=new people("張三");
document.write(zhangsan.say());
總結:這種構造類/對象的方法是推薦使用的
E.動態原型方式
這是在混合的建構函式/原型方式上改進的一種方式(提供更友好的編碼風格),他們功能是等價的
eg.1
function people(name){
this.name=name;
if(typeof people._initialized=="undefined"){
people.prototype.say=function(){
return "我的名字叫"+this.name;
};
people._initialized=true;
}
}
var zhangsan=new people("張三");
document.write(zhangsan.say());
var lisi=new people("李四");
document.write(lisi.say());
這樣處理的目的是建立對象的方法後下一次使用時不要再建立.
由於上面的原因,動態原型方式也是javascript中常用的一種建立類/對象的一種方式
F.混合工廠方式
混合工廠方式幾乎和工廠方式是一樣的.它同樣是先構造對象,然後再往對象中添加屬性和方法.不同的是,混合工廠方式產生對象時依舊使用new關鍵字.
eg.1
function people(){
var p_object=new Object;
p_object.name="張三";
p_object.say=function(){
alert("我叫張三");
}
return p_object; //返回對象
}
var zhangsan=new people;
var lisi=new people;
zhangsan.say();
lisi.say();
混合工廠方式和工廠方式以及經典方式(建構函式,原型方式)一樣會產生問題,不推薦使用
對各種構建類/對象方式的總結:
通常地,我們使用混合的建構函式/原型方式,即屬性使用建構函式方式,方法採用原型方式.當然,加強地,我們可以使用動態原型方式.
上面兩種方式是推薦使用的.
---->關於prototype的其他功能
1.給對象(包括本機物件)添加新的方法
比如Array對象,你可能需要添加一個方法toHexString,你可以這樣做:
Array.prototype.toHexString=function(){
//code here
}
2.重定義方法
實質是讓方法指向一個新的函數
Array.prototype.toHexString=function(){
//other code href
}