JS 建立物件的幾種方式
阿新 • • 發佈:2019-01-27
<script type="text/javascript">
/* 建立物件的幾種方式: */
// 1. 工廠方法:能建立並返回特定型別物件的工廠函式(factory function).
function createCar(sColor){
var car =new Object(); // 或者 var car = new Object ;// 物件屬性 car.color = sColor ;
// 物件方法
car.showColor =function (){
alert(123);
} ; // 記住,這裡一定要用 ; 表示結束 return car;// 這裡是 return car ; 而不是 return this.car ; 因為 this.car 為 undefined}
/*
呼叫此函式時,將建立物件,並賦予它所有必要的屬性,使用此方法建立 car 物件的兩個版本,
( oCar1 和 oCar2 ) ,他們的屬性完全一樣。
使用此方法存在的問題:
1. 語義上看起來不像使用帶有建構函式的 new 運算那麼正規.
2. 使用這種方式必須建立物件的方法。每次呼叫 createCar(),都要建立 showColor(),意味著每一個物件
都有自己的 showColor 版本,事實上,每一個物件都共享了是同一個函式.
有些開發者在工廠函式外定義物件的方法,然後通過屬性指向該方法。從而避免這個問題:
*/
function createCar2(sColor){
var car =new Object();
car.color = sColor ;
car.showColor = showColor ;
return car ;
}
function showColor(){
alert(this.color);
}
var oCar1 = createCar('red');
var oCar2 = createCar('yellow');
var oCar3 = createCar2('blue');
var oCar4 = createCar2('black');
/*
注意這兩個物件(oCar3 和 oCar4 ) 呼叫showColor 屬性的方式,雖然美其名曰是“屬性”,其實還是方法!!!
所以是 oCar3.showColor(); 而不是 oCar3.showColor ;
*/
oCar3.showColor();
oCar4.showColor();
/*
在這段重寫的程式碼中,在函式 createCar2() 前定義了函式showColor(), 在 createCar2() 內部,賦予物件一個已經
指向已經存在的 showColor() 函式的指標,從功能上講,這樣解決了重複建立物件的問題,但該函式看起來不像物件
的方法。
所有這些問題引起了開發者的定義建構函式的出現
*/
// 2. 建構函式方式
function Car(sColor){
this.color = sColor;
this.showColor =function(){
alert(this.color);
};
}var car1 =new Car('red');
car1.showColor();
/*
你可能已經注意到第一個的差別了,在建構函式內部無建立物件,而是使用 this 關鍵字,使用 new
運算子呼叫建構函式,在執行第一行程式碼前先建立一個物件,只有用 this 才能訪問該物件。然後可以
直接賦予 this 屬性,預設情況下是建構函式的返回值,(不必明確使用 return 運算子)。
這種方式在管理函式方面與工廠方法一樣都存在相同的問題.
*/// 3. 原型方式
function PCar(){
}
PCar.prototype.color ="blue";
var pcar1 =new PCar();
/*
呼叫 new Car()時,原型的所有屬性都被立即賦予要建立的物件,意味著所有的 PCar 例項存放的是指向
showColor() 函式的指標,從語義看起來都屬於一個物件,因此解決了前面兩種方式存在的問題。此外使用
該方法,還能使用 instanceof 運算子檢查給定變數指向的物件型別。因此下面的程式碼將輸出 true:
*/
alert(pcar1 instanceof PCar); // output "true"
/*
這個方法看起來不錯,遺憾的是,它並不盡人意。
1. 首先這個建構函式沒有引數。使用原型方式時,不能給建構函式傳遞引數初始化屬性值,因為 pcar1 和
pcar2 的屬性都等於 "blue"
2. 真正的問題出現在屬性指向的物件,而不是函式時,函式共享不會造成任何問題,但是物件卻是很少被多個
例項共享的。
*/
// 4. 混合的建構函式/原型方式(推薦)
/*
聯合使用建構函式和原型方式,就可像使用其他程式設計語言一樣建立物件,這種概念非常簡單,即用建構函式
定義物件的所有非函式屬性,用原型方式定義物件的函式屬性(方法)。
*/
function hCar(sColor){
this.color = sColor;
this.drivers =new Array('Mike','Sue');
}
hCar.prototype.showColor =function(){
alert(this.color);
}var hcar1 =new hCar('y color');
var hcar2 =new hCar('r color');
hcar1.drivers.push('Matt');
alert(hcar1.drivers); // output "Mike,Sue,Matt"alert(hcar2.drivers); // output "Mike,Sue"// 5. 動態原型方式 (推薦)/*
對於習慣使用其他開發語言的開發者來說,使用混合建構函式/原型方式感覺不那麼和諧。批評建構函式/原型方式的人
認為,在建構函式內找屬性,在外部找方法的做法不合理。所以他們設計了動態原型方式,以供更友好的編碼風格。
動態原型方式的基本想法與混合建構函式/原型方式 相同,即在建構函式內定義非函式的屬性,而函式的屬性則利用
原型屬性定義。唯一的區別是賦予物件方法的位置。下面是使用動態原型方法重寫的 Car 類:
*/
function DCar(sColor){
this.color = sColor;
this.drivers =new Array('Mike','Sue');
if(typeof DCar._initialized == 'undefined'){
DCar.prototype.showColor =function(){
alert(this.color);
}
}
DCar._initialized =true;
}var dcar1 =new DCar('y dcar');
var dcar2 =new DCar('b dcar');
dcar1.showColor();
dcar2.showColor();
alert(DCar._initialized); // output "true"alert(dcar1._initialized); // output "undefined"
</script>
/* 建立物件的幾種方式: */
// 1. 工廠方法:能建立並返回特定型別物件的工廠函式(factory function).
function createCar(sColor){
var car =new Object(); // 或者 var car = new Object ;// 物件屬性 car.color = sColor ;
// 物件方法
car.showColor =function (){
alert(123);
} ; // 記住,這裡一定要用 ; 表示結束
/*
呼叫此函式時,將建立物件,並賦予它所有必要的屬性,使用此方法建立 car 物件的兩個版本,
( oCar1 和 oCar2 ) ,他們的屬性完全一樣。
使用此方法存在的問題:
1. 語義上看起來不像使用帶有建構函式的 new 運算那麼正規.
2. 使用這種方式必須建立物件的方法。每次呼叫 createCar(),都要建立 showColor(),意味著每一個物件
都有自己的 showColor 版本,事實上,每一個物件都共享了是同一個函式.
有些開發者在工廠函式外定義物件的方法,然後通過屬性指向該方法。從而避免這個問題:
function createCar2(sColor){
var car =new Object();
car.color = sColor ;
car.showColor = showColor ;
return car ;
}
function showColor(){
alert(this.color);
}
var oCar1 = createCar('red');
var oCar2 = createCar('yellow');
var oCar3 = createCar2('blue');
var oCar4 = createCar2('black');
/*
注意這兩個物件(oCar3 和 oCar4 ) 呼叫showColor 屬性的方式,雖然美其名曰是“屬性”,其實還是方法!!!
所以是 oCar3.showColor(); 而不是 oCar3.showColor ;
*/
oCar3.showColor();
oCar4.showColor();
/*
在這段重寫的程式碼中,在函式 createCar2() 前定義了函式showColor(), 在 createCar2() 內部,賦予物件一個已經
指向已經存在的 showColor() 函式的指標,從功能上講,這樣解決了重複建立物件的問題,但該函式看起來不像物件
的方法。
所有這些問題引起了開發者的定義建構函式的出現
*/
// 2. 建構函式方式
function Car(sColor){
this.color = sColor;
this.showColor =function(){
alert(this.color);
};
}var car1 =new Car('red');
car1.showColor();
/*
你可能已經注意到第一個的差別了,在建構函式內部無建立物件,而是使用 this 關鍵字,使用 new
運算子呼叫建構函式,在執行第一行程式碼前先建立一個物件,只有用 this 才能訪問該物件。然後可以
直接賦予 this 屬性,預設情況下是建構函式的返回值,(不必明確使用 return 運算子)。
這種方式在管理函式方面與工廠方法一樣都存在相同的問題.
*/// 3. 原型方式
function PCar(){
}
PCar.prototype.color ="blue";
var pcar1 =new PCar();
/*
呼叫 new Car()時,原型的所有屬性都被立即賦予要建立的物件,意味著所有的 PCar 例項存放的是指向
showColor() 函式的指標,從語義看起來都屬於一個物件,因此解決了前面兩種方式存在的問題。此外使用
該方法,還能使用 instanceof 運算子檢查給定變數指向的物件型別。因此下面的程式碼將輸出 true:
*/
alert(pcar1 instanceof PCar); // output "true"
/*
這個方法看起來不錯,遺憾的是,它並不盡人意。
1. 首先這個建構函式沒有引數。使用原型方式時,不能給建構函式傳遞引數初始化屬性值,因為 pcar1 和
pcar2 的屬性都等於 "blue"
2. 真正的問題出現在屬性指向的物件,而不是函式時,函式共享不會造成任何問題,但是物件卻是很少被多個
例項共享的。
*/
// 4. 混合的建構函式/原型方式(推薦)
/*
聯合使用建構函式和原型方式,就可像使用其他程式設計語言一樣建立物件,這種概念非常簡單,即用建構函式
定義物件的所有非函式屬性,用原型方式定義物件的函式屬性(方法)。
*/
function hCar(sColor){
this.color = sColor;
this.drivers =new Array('Mike','Sue');
}
hCar.prototype.showColor =function(){
alert(this.color);
}var hcar1 =new hCar('y color');
var hcar2 =new hCar('r color');
hcar1.drivers.push('Matt');
alert(hcar1.drivers); // output "Mike,Sue,Matt"alert(hcar2.drivers); // output "Mike,Sue"// 5. 動態原型方式 (推薦)/*
對於習慣使用其他開發語言的開發者來說,使用混合建構函式/原型方式感覺不那麼和諧。批評建構函式/原型方式的人
認為,在建構函式內找屬性,在外部找方法的做法不合理。所以他們設計了動態原型方式,以供更友好的編碼風格。
動態原型方式的基本想法與混合建構函式/原型方式 相同,即在建構函式內定義非函式的屬性,而函式的屬性則利用
原型屬性定義。唯一的區別是賦予物件方法的位置。下面是使用動態原型方法重寫的 Car 類:
*/
function DCar(sColor){
this.color = sColor;
this.drivers =new Array('Mike','Sue');
if(typeof DCar._initialized == 'undefined'){
DCar.prototype.showColor =function(){
alert(this.color);
}
}
DCar._initialized =true;
}var dcar1 =new DCar('y dcar');
var dcar2 =new DCar('b dcar');
dcar1.showColor();
dcar2.showColor();
alert(DCar._initialized); // output "true"alert(dcar1._initialized); // output "undefined"
</script>