從基礎講起,從重點講起!我覺得祝子這個系列的文章非常好,不管是對于javascript的入門同學還是有一定javascript經驗的老手都是個很好的系統學習資料。來自經典的《javascript高級程序設計》。
原文出處:http://www.tkk7.com/ilovezmh/archive/2007/04/16/111098.html
一、定義類或對象
1.工廠方式
創建對象car
var oCar = new Object;
oCar.color = "red";
oCar.doors = 4;
oCar.mpg = 23;
oCar.showColor = function(){
alert(this.corlor);
};
創建多個car
function createCar(color, doors, mpg) {
var tempcar = new Object;
tempcar.color = color;
tempcar.doors = doors;
tempcar.mpg = mpg;
tempcar.showColor = function () {
alert(this.color)
};
return tempcar;
}
var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor(); //outputs "red"
car2.showColor(); //outputs "blue"
這個例子中,每次調用函數createCar(),都要創建新函數showColor(),意味著每個對象都有自己的showColor()版本,事實上,每個對象都共享了同一個函數。
有些開發者在工廠函數外定義對象的方法,然后通過屬性指向該方法,從而避開這個問題。
function showColor(){
alert(this.color);
}
function createCar(color, doors, mpg) {
var tempcar = new Object;
tempcar.color = color;
tempcar.doors = doors;
tempcar.mpg = mpg;
tempcar.showColor = showColor;
return tempcar;
}
var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor(); //outputs "red"
car2.showColor(); //outputs "blue"
從功能上講,這樣解決了重復創建函數對象的問題,但該函數看起來不像對象的方法。所有這些問題引發了開發者定義的構造函數的出現。
2.構造函數方法
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function () {
alert(this.color)
};
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.showColor(); //outputs "red"
oCar2.showColor(); //outputs "blue"
就像工廠函數,構造函數會重復生成函數,為每個對象都創建獨立的函數版本。不過,也可以用外部函數重寫構造函數,同樣,這么做語義上無任何意義。
3.原型方式
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors= 4;
Car.prototype.mpg= 23;
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
var oCar2 = new Car();
它解決了前面兩種方式存在的兩個問題。但并不盡人意。首先,這個構造函數沒有參數。使用原型方式時,不能通過構造函數傳遞參數初始化屬性的值,這點很令人計厭,但還沒完,真正的問題出現在屬性指向的是對象,而不是函數時??紤]下面的例子:
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors= 4;
Car.prototype.mpg= 23;
Car.prototype.drivers = new Array("Mike","Sue");
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue,Matt"
4.混合的構造函數/原型方式
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
}
Car.prototype.showColor = function () {
alert(this.color);
};
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
現在就更像創建一般對象了。所有的非函數屬性都有構造函數中創建,意味著又可用構造函數的參數賦予屬性默認值了。因為只創建showColor()函數的一個實例,所以沒有內存浪費。
5.動態原型方法
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function () {
alert(this.color);
};
Car._initialized = true;
}
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
動態原型方法的基本想法與混合的構造函數/原型方式相同,即在構造函數內定義非函數屬性,而函數屬性則利用原型屬性定義。唯一的區別是賦予對象方法的位置。
6.混合工廠方式
這種方式通常是在不能應用前一種方式時的變通方法。它的目的是創建假構造函數,只返回另一種對象的新實例。
function Car() {
var tempcar = new Object;
tempcar.color = "red";
tempcar.doors = 4;
tempcar.mpg = 23;
tempcar.showColor = function () {
alert(this.color)
};
return tempcar;
}
與經典方式不同,這種方式使用new運算符,使它看起來像真正的構造函數。
7.采用哪種方式
如前所述,目前使用最廣泛的是混合的構造函數/原型方式。些外,動態原型方法也很流行,在功能上與前者等價,可以采用這兩種方式中的任何一種。
二、修改對象
1.創建新方法
可以用prototype屬性為任何已有的類定義新方法,就像處理自己的類一樣。
例:
Array.prototype.indexOf = function(vItem){
for(var i=0;i<this.length;i++){
if(vItem == this[i]){
return i;
}
}
retunr -1;
}
最后,如果想給ECMAScript中的每個本地對象添加新方法,必須在Object對象的prototype屬性上定義它。
2.重定義已有方法
就像能給自己的類定義新方法一樣,也可重定義已有的方法。函數名只是指向函數的指針,因此可以輕易地使它指向其他函數。
如
Function.prototype.toString = function(){
return "Function code hidden";
}
function sayHi(){
alert("hi");
}
alert(sayHi.toString()); //outputs "Function code hidden"
posted on 2007-04-18 23:31
cresposhi 閱讀(1349)
評論(3) 編輯 收藏