javascript工廠函數(factory function)vs構造函數(constructor function)


如果你從其他語言轉到javascript語言的開發,你會發現有很多讓你暈掉的術語,其中工廠函數(factory function)和構造函數(constructor function)就是其中的一個。本文試圖理順這兩者之間的區別.

Factory functions

工廠函數是將返回一個新的object的任何不是類或者構造函數的函數。在js中,任何函數都能夠返回一個object.如果我們不是通過new function()的方式來獲得這個對象的,那么她就是一個factory工廠函數.

function person(firstName, lastName, age) {
  const person = {};
  person.firstName = firstName;
  person.lastName = lastName;
  person.age = age;
  return person;
}

上面的js代碼會創建一個new object並且將傳入的參數賦值給到該object的屬性上,並且返回該new object.

Constructor functions

工廠函數和構造函數區別僅僅在於其用戶場景use case以及約定俗成的convention不同,基本上兩者是相似的。對於構造函數,人們慣例convention使用首字母大寫方式來表示這是一個constructor構造函數.構造函數往往其use case是需要需要通過 new 關鍵字調用返回類似對象的場景,並且隨后我們可以通過 instanceof 關鍵字來做實例類型檢查的場景。

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}

通過new關鍵字來創建新的對象objects

如上面所說,工廠函數和構造函數基本上是一樣的,你現在估計有以下問題:

1. 我們可以對工廠函數來使用 new 關鍵字嗎?

2.如果針對工廠函數和構造函數,我們使用 new 關鍵字將會發生什么呢?

3. 如果針對構造函數並不使用 new 關鍵字去創造對象會怎么樣呢?

下面我們將試圖回答上面的幾個問題.

我們先使用new關鍵,應用到工廠函數和構造函數身上,並且console.log打印以下,看看有什么不同.

使用 new factory 函數

function person(firstName, lastName, age) {
  const person = {};
  person.firstName = firstName;
  person.lastName = lastName;
  person.age = age;
  return person;
}
const mike = new person('mike', 'grand' 23);

 

 

 

 使用constructor function

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}
const mike = new Person('mike', 'grand', 23);

 

 

 

 new操作符的背后

通過 new 構造函數方式創建object時有以下幾個過程發生:

function Person(firstName, lastName, age) {
    // this = {};
    // this.__proto__ = Person.prototype;
    // Set up logic such that: if
    // there is a return statement
    // in the function body that
    // returns anything EXCEPT an
    // object, array, or function:
    //     return this (the newly
    //     constructed object)
    //     instead of that item at
    //     the return statement;
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    // return this;
}

上面的// 注釋行內容就是當使用new ConstructFunction()創建新對象時js引擎自動增加的部分偽代碼。

1.創建一個新的空object並且bind到this關鍵字

2.設置該對象的__proto__指向為構造函數的prototype.

3.增加以下邏輯:如果函數體中有return語句,但是返回的如果不是Object,array,或者function的話,則直接返回this指針

4.返回this object

我們把上面的邏輯增加到普通的函數體內,看看new factory調用時的結果:

function person(firstName, lastName, age) {
    // this = {};
    // this.__proto__ = Person.prototype; 
 
    // Set up logic such that: if
    // there is a return statement
    // in the function body that
    // returns anything EXCEPT an
    // object, array, or function:
    //     return this (the newly
    //     constructed object)
    //     instead of that item at
    //     the return statement;
    const person = {};
    person.firstName = firstName;
    person.lastName = lastName;
    person.age = age;
    return person;
    // return this;
}

我們看到由於person是一個object,因此return this就會被忽略,而是直接返回person對象。

如果使用構造函數時,忘記使用 new 關鍵字,會怎樣?

function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}
const mike = new Person('mike', 'grand', 23);
const bob = Person('bob', 'grand', 23);

 

 

我們可以看到bob為undefined,原因是Person函數本身並沒有返回任何內容,因此bob就為undefined.

但是我們會發現firstName,lastName和age這幾個屬性都被添加到了window全局對象上了。

 

 https://medium.com/@chamikakasun/javascript-factory-functions-vs-constructor-functions-585919818afe

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM