HOWTO · JavaScript

多個 JavaScript 建構函式的模式

本文將教你 JavaScript 中多個建構函式的五種不同模式。這些模式包括引數嗅探、靜態方法、函式中的方法、具有預設值的可選引數和單個物件字面量。

本頁內容

本文將教你 JavaScript 中多個建構函式的五種不同模式。以下是多個建構函式的模式。

  1. 引數嗅探
  2. 靜態方法
  3. 函式中的方法
  4. 帶預設值的可選引數
  5. 單物件字面量

JavaScript 中的引數嗅探

引數嗅探是關於檢查引數型別併為其建立建構函式。如果引數是字串,你可以使用 typeof 運算子來確定字串。

你還可以指定建構函式如何為字串工作併為其他資料型別執行此操作。

程式碼:

function ConstructWithParam(a) {
  if (typeof (a) === 'string') {
    this.name = 'You supplied a string';
    console.log(this.name);
  }

  if (typeof (a) === 'number') {
    this.name = 'You supplied a number';
    console.log('You supplied a number');
  }
}

let aNumber = new ConstructWithParam(2);
let aString = new ConstructWithParam('Hello');

console.log(aNumber, aString);

輸出:

You supplied a number
You supplied a string
Object { name: "You supplied a number" }
Object { name: "You supplied a string" }

在這種情況下,我們在控制檯中記錄了一條訊息。

JavaScript 中的靜態方法

你可以建立返回新類例項的靜態方法,從而產生多個建構函式。如果你想嚴格地例項化一個類或建立具有複雜組合的物件,你會發現這種方法很有用。

程式碼:

class multiConstructor {
  constructor(w = '', x = '', y = '', z = '') {
    this.w = w;
    this.x = x;
    this.y = y;
    this.z = z;
  }

  static WandXInstance(w, x) {
    return new multiConstructor(w, x, '', '');
  }

  static YandZInstance(y, z) {
    return new multiConstructor('', '', y, z)
  }
}

let objectWithDefaultConstructor = new multiConstructor('Alpha', 'Bravo');
let objectFromStaticMethod = multiConstructor.YandZInstance('Charlie', 'Delta');

console.log(objectWithDefaultConstructor);
console.log(objectFromStaticMethod);

輸出:

Object { w: "Alpha", x: "Bravo", y: "", z: "" }
Object { w: "", x: "", y: "Charlie", z: "Delta" }

這些靜態方法使用不同的類引數並返回該類的新例項。你不僅限於使用預設建構函式建立一種型別的例項。

函式中的 JavaScript 方法

函式可以像其他所有物件一樣具有屬性和方法。使用函式中的方法,你可以使用這些方法來服務於建構函式的目的。

因此,你可以使用替代引數建立物件。儘管這些方法不是一個精確的建構函式,但在這種情況下它就是你所需要的。

我們在下面的程式碼中定義了一個函式並向它新增了一個方法。

程式碼:

function MultiCon(multicon) {
  this.multicon = multicon;
}

MultiCon.prototype = {
  multiCon: null,
}

                     MultiCon.someComponents =
    function(a, b) {
  var ab = a + b;
  return new MultiCon(ab);
}

var x = MultiCon.someComponents('Mada', 'Gascar');
var y = new MultiCon('Mada');

console.log(x, y);

輸出:

Object { multicon: "MadaGascar" }
Object { multicon: "Mada" }

在此示例中,使用 new 關鍵字或使用 added 方法呼叫函式會產生相同的結果。

JavaScript 中具有預設值的可選引數

你可以向類建構函式新增可選引數,這些引數可以具有預設值。建立類例項時,我們不必指定所有引數。

程式碼:

class Employee {
  constructor(first_name, last_name, date_of_birth) {
    this.first_name = first_name;
    this.last_name = last_name;
    this.date_of_birth = date_of_birth;
  }
}

const newEmployee =
    new Employee('Scarlett', 'Johannsen', new Date(1989, 2, 20));
const newEmployee_noDOB = new Employee('Magaret', 'Tatcher');
const newEmployee_firstNameOnly = new Employee('John');
const newEmployee_noBioData = new Employee();

console.log(newEmployee);
console.log(newEmployee_noDOB);
console.log(newEmployee_firstNameOnly);
console.log(newEmployee_noBioData);

輸出:

Object { first_name: "Scarlett", last_name: "Johannsen", date_of_birth: Date Mon Mar 20 1989 00:00:00
Object { first_name: "Magaret", last_name: "Tatcher", date_of_birth: undefined }
Object { first_name: "John", last_name: undefined, date_of_birth: undefined }
Object { first_name: undefined, last_name: undefined, date_of_birth: undefined }

但是,你無法知道該類是否從呼叫程式碼中接收到一個或多個值。你可以從之前的輸出中注意到這一點,其中我們有一系列 undefined 值。

你可以設定類在沒有收到任何引數時可以使用的預設值來處理這個問題。

程式碼:

class Employee {
  constructor(
      first_name = 'New Employee', last_name = 'New Employee',
      date_of_birth = '1970-01-01') {
    this.first_name = first_name;
    this.last_name = last_name;
    this.date_of_birth = date_of_birth;
  }
}

const newEmployee_noBioData = new Employee();
const newEmployee_firstNameOnly = new Employee('John');

console.log(newEmployee_noBioData);
console.log(newEmployee_firstNameOnly);

輸出:

Object { first_name: "New Employee", last_name: "New Employee", date_of_birth: "1970-01-01" }
Object { first_name: "John", last_name: "New Employee", date_of_birth: "1970-01-01" }

從類建立物件時,你可以使用 undefined 代替預設值。undefined 關鍵字告訴類在類定義中使用預設值。

class Employee {
  constructor(
      first_name = 'New Employee', last_name = 'New Employee',
      date_of_birth = '1970-01-01') {
    this.first_name = first_name;
    this.last_name = last_name;
    this.date_of_birth = date_of_birth;
  }
}

const newEmployee_firstNameOnly = new Employee(undefined, 'Martinez');
console.log(newEmployee_firstNameOnly);

輸出:

Object { first_name: "New Employee", last_name: "Martinez", date_of_birth: "1970-01-01" }

JavaScript 中的單個物件字面量

如果你有許多呼叫程式碼可能不使用的可選標誌,則將可選引數放入單個物件中將很有用。物件屬性沒有型別檢查或 linting,因此你無法判斷屬性名稱是否有錯誤。

程式碼:

class System {
  constructor(hardware_maker, chipset_maker, operatingSystem = {}) {
    this.hardware_maker = hardware_maker;
    this.chipset_maker = chipset_maker;
    this.operatingSystem = operatingSystem;
  }
}

const newSystem = new System('Intel', 'Nvidia', {
  'OS Version': 'Windows 7',
  'Service Pack Update': '2009-03-05',
  'Windows Update Last Checked': '2009-03-05'
});
const newSystem2 = new System('AMD', 'GeoFeorce');

console.log(newSystem);
console.log(newSystem2);

輸出:

Object { hardware_maker: "Intel", chipset_maker: "Nvidia", operatingSystem: { "OS Version": "Windows 7", "Service Pack Update": "2009-03-05", "Windows Update Last Checked": "2009-03-05" } }
Object { hardware_maker: "AMD", chipset_maker: "GeoFeorce", operatingSystem: {} }

在上面的程式碼中,我們設定了一個物件。該物件將獲取 operatingSystem 物件內的作業系統詳細資訊。