JavaScript 構(gòu)造器模式

2018-08-02 16:23 更新

構(gòu)造器模式

在面向?qū)ο缶幊讨?,?gòu)造器是一個當新建對象的內(nèi)存被分配后,用來初始化該對象的一個特殊函數(shù)。在JavaScript中幾乎所有的東西都是對象,我們經(jīng)常會對對象的構(gòu)造器十分感興趣。

對象構(gòu)造器是被用來創(chuàng)建特殊類型的對象的,首先它要準備使用的對象,其次在對象初次被創(chuàng)建時,通過接收參數(shù),構(gòu)造器要用來對成員的屬性和方法進行賦值。

對象創(chuàng)建

下面是我們創(chuàng)建對象的三種基本方式:

下面的每一種都會創(chuàng)建一個新的對象:

var newObject = {};

// or
var newObject = Object.create( null );

// or
var newObject = new Object();

最后一個例子中"Object"構(gòu)造器創(chuàng)建了一個針對特殊值的對象包裝,只不過這里沒有傳值給它,所以它將會返回一個空對象。

有四種方式可以將一個鍵值對賦給一個對象:

// ECMAScript 3 兼容形式

// 1\. “點號”法

// 設(shè)置屬性
newObject.someKey = "Hello World";

// 獲取屬性
var key = newObject.someKey;

// 2\. “方括號”法

// 設(shè)置屬性
newObject["someKey"] = "Hello World";

// 獲取屬性
var key = newObject["someKey"];

// ECMAScript 5 僅兼容性形式
// For more information see: http://kangax.github.com/es5-compat-table/

// 3\. Object.defineProperty方式

// 設(shè)置屬性
Object.defineProperty( newObject, "someKey", {
    value: "for more control of the property's behavior",
    writable: true,
    enumerable: true,
    configurable: true
});

// 如果上面的方式你感到難以閱讀,可以簡短的寫成下面這樣:

var defineProp = function ( obj, key, value ){
  config.value = value;
  Object.defineProperty( obj, key, config );
};

// 為了使用它,我們要創(chuàng)建一個“person”對象
var person = Object.create( null );

// 用屬性構(gòu)造對象
defineProp( person, "car",  "Delorean" );
defineProp( person, "dateOfBirth", "1981" );
defineProp( person, "hasBeard", false );

// 4\. Object.defineProperties方式

// 設(shè)置屬性
Object.defineProperties( newObject, {

  "someKey": { 
    value: "Hello World", 
    writable: true 
  },

  "anotherKey": { 
    value: "Foo bar", 
    writable: false 
  } 

});

// 3和4中的讀取屬行可用1和2中的任意一種

在這本書的后面一點,這些方法會被用于繼承,如下:

// 使用:

// 創(chuàng)建一個繼承與Person的賽車司機
var driver = Object.create( person );

// 設(shè)置司機的屬性
defineProp(driver, "topSpeed", "100mph");

// 獲取繼承的屬性 (1981)
console.log( driver.dateOfBirth );

// 獲取我們設(shè)置的屬性 (100mph)
console.log( driver.topSpeed );

基礎(chǔ)構(gòu)造器

正如我們先前所看到的,Javascript不支持類的概念,但它有一種與對象一起工作的構(gòu)造器函數(shù)。使用new關(guān)鍵字來調(diào)用該函數(shù),我們可以告訴Javascript把這個函數(shù)當做一個構(gòu)造器來用,它可以用自己所定義的成員來初始化一個對象。

在這個構(gòu)造器內(nèi)部,關(guān)鍵字this引用到剛被創(chuàng)建的對象?;氐綄ο髣?chuàng)建,一個基本的構(gòu)造函數(shù)看起來像這樣:

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 );

// 打開瀏覽器控制臺查看這些對象toString()方法的輸出值
// output of the toString() method being called on
// these objects
console.log( civic.toString() );
console.log( mondeo.toString() );

上面這是個簡單版本的構(gòu)造器模式,但它還是有些問題。一個是難以繼承,另一個是每個Car構(gòu)造函數(shù)創(chuàng)建的對象中,toString()之類的函數(shù)都被重新定義。這不是非常好,理想的情況是所有Car類型的對象都應(yīng)該引用同一個函數(shù)。 這要謝謝 ECMAScript3和ECMAScript5-兼容版,對于構(gòu)造對象他們提供了另外一些選擇,解決限制小菜一碟。

使用“原型”的構(gòu)造器

在Javascript中函數(shù)有一個prototype的屬性。當我們調(diào)用Javascript的構(gòu)造器創(chuàng)建一個對象時,構(gòu)造函數(shù)prototype上的屬性對于所創(chuàng)建的對象來說都看見。照這樣,就可以創(chuàng)建多個訪問相同prototype的Car對象了。下面,我們來擴展一下原來的例子:

function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;

}

// 注意這里我們使用Note here that we are using Object.prototype.newMethod 而不是
// Object.prototype ,以避免我們重新定義原型對象
Car.prototype.toString = function () {
  return this.model + " has done " + this.miles + " miles";
};

// 使用:

var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );

console.log( civic.toString() );
console.log( mondeo.toString() );

通過上面代碼,單個toString()實例被所有的Car對象所共享了。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號