建立對象的方式(1)
方式一、對象字面量的方式
var student = {
name : 'lisi',
age : 18,
call : function(){
console.log("我叫"+this.name);
}
}
上面就建立了一個student對象,但是上面這種方式隻适用于建立單個對象。其實很多js插件的開發都用到這種方式對象字面量+原型模式
方式二、工廠模式
functionstudent(name,age){
var obj = new Object(); //一個空對象
obj.name = name; //聲明一個name屬性
obj.age = age;
obj.say = function(){ //聲明一個方法
console.log("我叫"+obj.name);
}
return obj;
}
var student1 = student('lisi',20);
student1.say();
console.log(student1 instanceof student);//false
其實這個很好了解,就是把建立對象的過程及結果放到函數裡面包裝起來。但是用這種方式建立的對象無法被識别類型。就像上面傳回false一樣,無法判斷student1是否是student類型。再拿一個熟悉的例子說:
var arr = newArray();
console.log(arrinstanceof Array); //true
方式三、構造函數模式
functionStudent(name,age){
this.name = name;
this.age = age;
this.say = function(){
console.log("我叫"+this.name);
}
}
var student1 = newStudent('lisi',20);
student1.say();
console.log(student1 instanceof student);//true
首先函數名稱的首字母要大寫,主要是為了差別于普通函數。建立對象是在函數外面。這種方式建立的對象類型是能夠被識别的。當然上面的構造函數你也可以當作普通函數調用(題外話)
這種方式就沒有缺點了嗎?答案是否定的。請看下面的例子:
function a(){
console.log(1);
}
var b = a;
var c = a;
console.log(b===c);//true
我們都知道函數被建立之後,就被分别到記憶體中。變量b,c隻是引用函數的指針,實際上他們調用的函數是一樣的。而
var student1 = newStudent('lisi',20);
var student2 = new Student('san',18);
var b = student1.say;
var c = student2.say;
console.log(b===c);//false
有此可知,student1和student2調用的say并不是同一個函數
實際上在調用構造函數時這個方法被重新聲明了,顯然浪費資源
say :function(){} 等價于 new Function()
是以為了不浪費資源,我們又可以這樣
functionStudent(name,age){
this.name = name;
this.age = age;
this.say = say;
}
function say(){
console.log("我叫"+this.name);
}
var student1 = newStudent('lisi',20);
var student2 = newStudent('san',18);
var b = student1.say;
var c = student2.say;
console.log(b===c);//這時傳回的是true
但是這裡又有一個問題了,say這個函數是window下全局的函數,并沒有制定是哪個對象的,顯然會造成一定混亂。是以為了解決這種缺點,js又提供了一種方式原型模式(其實就是對上面幾種模式的一種擴充)