在經典的面向對象程式設計語言中,constructor是一個特殊的方法,被用來初始化一個建立的對象,一旦該對象被配置設定記憶體話。
在JavaScript中幾乎所有的東西都是一個對象,然而常常引起我們興趣的是對象的constructor。
對象的構造函數用于建立特定類型的對象(既要準備使用對象,也要接收參數),構造函數在建立對象時可以用來設定成員屬性和方法的值。
建立對象
在JavaScript中建立對象的三種通用方法如下:
// 每種方法将建立一個空對象
var newObject = {}
// or
var newObject = Object.create( Object.prototype )
// or
var newObject = new Object();
最後一個方法實作對象的建立可以傳入指定的值,如果沒有傳遞,将建立一個空對象,然後傳回它。
傳入String,傳回String,類似于new String();
傳入Number,傳回Number,類似于new Number();
傳入Object,傳回Object,相當于沒傳
為對象指定鍵和值有如下四種方法:
相容ES3的方法
// 1. `.`(Dot) 文法
// 設定屬性
newObject.someKey = 'Hello world';
// 擷取屬性
var value = newObject.somekey;
// 2. '[]'方括号文法
// 設定屬性
newObject["someKey"] = "Hello World";
// 擷取屬性
var value = newObject["someKey"];
相容ES5的方法(要了解更多的資訊,請轉
http://kangax.github.com/es5-compat-table/)
// 3. Object.defineProperty
// 設定屬性
Object.defineProperty(newObject, "someKey", {
value: "Hello World",
writable: true,
enumerable: true,
configurable: true
})
// 擷取屬性的方法,用1,2中方法即可
// 詳細了解Object.defineProperty的使用可參考[https://segmentfault.com/a/1190000007434923](https://segmentfault.com/a/1190000007434923)
// 4. Object.defineProperties
// 設定屬性
Object.defineProperties(newObject, {
"someKey": {
value: "Hello World",
writable: true
},
"anotherKey": {
value: "Ha ha",
writable: true
}
})
// 擷取屬性的方法,用1,2中方法即可
對象的繼承
前面我們說到幾種的對象的建立方式,在三種對象的建立中,第一種方式最簡單,效率更高,其他兩種内部都用了對象的繼承,如果沒有傳入任何參數,實作和第一種相似。下面試第二三種建立對象的執行個體:
// 第二種
var obj = {};
obj.a=1;
obj.a -> 1
var obj2 = Object.create(obj)
obj2.a -> 1
// 第三種
var obj = {};
obj.a = 1;
obj.a -> 1
var obj2 = new Object(obj);
obj2.a -> 1
是以隻是要建立一個空對象,第一種方法更好,要實作對象的繼承用第二三種方法,第二三種方法的差別在于前者是ES3,後者是ES5。
// Object.create 的内部實作如下:
Object.create = function(o) {
function F(){}
F.prototype=o;
return new F();
}
constructor 基礎
衆所周知,JavaScript一門不支援
class
這個概念,但是它支援對象的構造函數,通過關鍵字
new
我們想要一個構造函數建立一個對象和它用函數定義的成員。
在constructor的内部,
this
關鍵字是被建立的新對象的引用。重溫對象的建立過程,一個基礎的 constructor 如下所示:
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
}
// 用法:
// 建立一個car的執行個體
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );
// 結果輸出
console.log( civic.toString() ); -> "Honda Civic has done 20000 miles"
console.log( mondeo.toString() ); -> "Ford Mondeo has done 5000 miles"·
如果現在就把它定義為一個設計模式相信,很多人對不會用它,因為它存在着一些問題。其中一個就是繼承性,另一個是每建立一個對象執行個體,
toString()
方法都要被重新定義,理想的實作方式是要實作
toString()
在不同的執行個體類型之間共享。
constructor 和 prototype
在JavaScript中,
Function
像其他對象一樣,有一個
prototype
。當我們用contructor建立一個對象,所有constructor的 prototype上的屬性都将被新對象繼承。是以上面的例子我們可以修改如下:
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
}
Car.prototype.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
// 用法:
// 建立一個car的執行個體
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );
// 結果輸出
console.log( civic.toString() ); -> "Honda Civic has done 20000 miles"
console.log( mondeo.toString() ); -> "Ford Mondeo has done 5000 miles"·
這樣,
toString()
将實作在不同的對象執行個體間的共享。
其它設計模式相關文章請轉
‘大處着眼,小處着手’——設計模式系列