對象是什麼
從JavaScript定義上講對象是無序屬性的集合,其屬性可以包含基本值、對象或函數。也就是說對象是一組沒有特定順序的屬性,每個屬性會映射到一個值上,是一組索引值對,值可以是資料或對象。
最簡單的對象
JavaScript的一對花括弧{}就可以定義一個對象,這樣的寫法實際上和調用Object的建構函式一樣
複製代碼 代碼如下:
var obj={};
var obj2=new Object();
這樣構建出來的對象僅僅包含一個指向Object的prototype的指標,可以使用一些valueOf、hasQwnProperty等方法,沒有多大實際作用,自訂對象嘛總要有一些自訂的屬性、方法神馬的。
複製代碼 代碼如下:
var obj={};
obj.a=0;
obj.fn=function(){
alert(this);
}
var obj2={
a:0,
fn:function(){
alert(this);
}
}
可以在定義完對象後通過”.”為其添加屬性和方法,也可以使用字面量賦值方法在定義對象的時候為其添加屬性和方法,這樣建立的對象,其方法和屬性可以直接使用對象引用,類似於類的靜態變數和靜態函數,這樣建立對象有一個明顯缺陷——在定義大量對象的時候很費力,要一遍遍的寫幾乎是重複的代碼。
抽象一下
既然是重複代碼就可以抽象出來,用函數來做這些重複工作,在建立對象的時候調用一個專門建立對象的方法,對於不同的屬性值只需要傳入不同參數即可。
複製代碼 代碼如下:
function createObj(a,fn){
var obj={};
obj.a=a;
obj.fn=fn;
return obj;
}
var obj=createObj(2,function(){
alert(this.a);
});
這樣在建立大量對象的時候,就可以通過調用此方法來做一些重複工作了,這種方式也不完美,因為在很多時候需要判斷對象的類型,上面代碼建立出來的對象都是最原始的Object對象執行個體,只是拓展了一些屬性和方法。
有型一些
又是function登場的時候,JavaScript中function就是個對象,在建立對象的時候打可以拋開上面createObj方法,直接使用function作為對象,怎麼實現複用呢,這就在於function作為對象的特殊性了。
1. function可以接受參數,可以根據參數來建立相同類型不同值的對象
2. function作為建構函式(通過new操作符調用)的時候會返回一個對象,在貧下中農版jQuery中提到過一些建構函式的基本知識,簡單複製一下
建構函式的傳回值分為兩種情況,當function沒有return語句或者return回一個基本類型(bool,int,string,undefined,null)的時候,返回new 建立的一個匿名對象,該對象即為函數執行個體;如果function體內return一個參考型別對象(Array,Function,Object等)時,該對象會覆蓋new建立的匿名對象作為傳回值。
3. 那麼使用function怎麼解決類型識別問題呢,每個function執行個體對象都會有一個constructor屬性(也不是“有”,而是可以對應),這個屬性就可以指示其構造是誰,也可以使用instanceof 操作符來做判斷對象是否為XXX的執行個體。
不能光說不練,上代碼
複製代碼 代碼如下:
function Person(name){
this.name=name;
this.fn=function(){
alert(this.name);
}
}
var person1=new Person('Byron');
console.log(person1.constructor==Person);//true
console.log(person1 instanceof Person); //true
這樣就完美了吧,也不是!雖然建構函式可以是對象有型,但對象的每個執行個體中的方法都要重複一遍!
複製代碼 代碼如下:
function Person(name){
this.name=name;
this.fn=function(){
alert(this.name);
}
}
var person1=new Person('Byron');
var person2=new Person('Frank');
console.log(person1.fn==person2.fn);//false
看看看,雖然兩個執行個體的fn一模一樣,但是卻不是一回事兒,這如果一個function對象有一千個方法,那麼它的每個執行個體都要包含這些方法的copy,很讓記憶體無語啊。
不玩兒虛的了
究竟有沒有一種近乎完美的構造對象的方式,及不用做重複工作,又有型,對象通用方法又不必重複?其實可以發現使用function已經距離要求和接近了,只差那麼一點兒——需要一個所有function對象的執行個體共用的容器,在這個容器記憶體發執行個體需要共用的屬性和方法,正好這個容器是現成的——prototype,不瞭解prototype的同學可以看看JavaScript prototype
複製代碼 代碼如下:
function Person(name){
this.name=name;
}
Person.prototype.share=[];
Person.prototype.printName=function(){
alert(this.name);
}
var person1=new Person('Byron');
var person2=new Person('Frank');
console.log(person1.printName==person2.printName);//true
這樣每個Person的執行個體都有自己的屬性name,又有所有執行個體共用的屬性share和方法printName,基本問題都解決了,對於一般的對象處理就可以始終這個有型又有愛的建立對象模式了。