1.Object 模式
var o1 = {};//字面量的表現形式
var o2 = new Object;
2.工廠模式
function createCar(name,age){
var oTemp = new Object();
oTemp.name = name;//直接給對象添加屬性,每個對象都有直接的屬性
oTemp.age = age;
oTemp.showName = function () {
alert(this.name);
};//每個對象都有一個 showName 方法版本
return oTemp;
}
createCar("tom").showName();
減少了重復代碼,但是不能夠識別對象,所有實例都是object類型的。
3.構造器模式
function Car(sColor,iDoors){ //聲明為構造器時需要將函數名首字母大寫
this.color = sColor; //構造器內直接聲明屬性
this.doors = iDoors;
this.showColor = function(){
return this.color;
};//每個 Car 對象都有自己的 showColor方法版本
this.showDoor = function () {
return this.doors;
}
}
每個方法在每個實例上都要重新實現一遍,一是耗資源,二是創建兩個或者多個完成同樣任務的Function沒有必要,三是有this在,沒必要在代碼執行前就把函數綁定到特定對象上。
4.prototype模式
function Person(){}
Person.prototype.name="lxy";
Person.prototype.age=22;
Person.prototype.job="Software Engineer";
Person.prototype.sayName=function(){
alert(this.name);
}
var lxy=new Person();
lxy.sayName();
原型也有它本身的問題,共享的屬性值如果是引用類型,一個實例對該屬性的修改會影響到其他實例。
5.構造器方式與原型方式的混合模式
//每個對象有專屬的屬性不會與其他對象共享
function Car(sColor,iDoors){
this._color = sColor;//私有屬性變量名稱頭加下劃線標識
this._doors = iDoors;
this.drivers = new Array("Mike","John");//公有屬性標識
}
//所有對象共享一個方法版本,減少內存浪費
Car.prototype.showColor = function () {
alert(this._color);
};
var car = new Car("red",4);
這種構造函數與原型混合模式,是目前使用最廣泛、認同度最高的一種創建自定義類型的方法。可以說,這是用來定義引用類型的一種默認模式。其實原型就是為構造函數服務的,配合它來創建對象,想要只通過原型一勞永逸的創建對象是不可取的,因為它只管創建共享的屬性和方法,剩下的就交給構造函數來完成。
6.動態原型模式
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
//使用標志(_initialized)來判斷是否已給原型賦予了任何方法,保證方法永遠只被創建并賦值一次
if(typeof Car._initialized == "undefined"){//因為這里的標記是附加在類上,故如果后期直接對其進行修改,還是有可能出現再次創建的情況
Car.prototype.showColor = function () {//為Car添加一個存放在 prototype 域的方法
alert(this.color);
};
Car._initialized = true;//設置一個靜態屬性
}
}
var car = new Car("red",3,25);
使用動態原型時,不能使用對象字面量重寫原型。如果在已經創建了實例的情況下重寫原型,那么就會切斷現有實例與新原型之間的聯系。
7.混合工廠模式
function Car(){
var oTempCar = new Object;
oTempCar.color = "blue";
oTempCar.doors = 4;
oTempCar.showColor = function () {
alert(this.color);
};
return oTempCar;
}
var car = new Car();
由于在 Car6()構造函數內部調用了 new 運算符,所以將忽略第二個 new 運算符(位于構造函數之外),
附:new操作符具體干了什么呢?
1、創建一個空對象,并且 this 變量引用該對象,同時還繼承了該函數的原型。
2、屬性和方法被加入到 this 引用的對象中。
3、新創建的對象由 this 所引用,并且最后隱式的返回 this 。
//等價于下面代碼
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);