搜尋
首頁web前端js教程JS的class、建構子、工廠函式使用方法

這次帶給大家JS的class、建構子、工廠函式使用方法,使用JSclass、建構子、工廠函式的注意事項有哪些,下面就是實戰案例,一起來看一下。

到了ES6時代,我們創建物件的手段又增加了,在不同的場景下我們可以選擇不同的方法來建立。現在就主要有三種方法來建構對象,class關鍵字,建構函數,工廠函數。他們都是創造物件的手段,但是卻又有不同的地方,平時開發時,也需要針對這不同來選擇。

首先我們來看一下,這三種方法是怎麼樣的

// class 关键字,ES6新特性
class ClassCar {
 drive () {
  console.log('Vroom!');
 }
}
const car1 = new ClassCar();
console.log(car1.drive());
// 构造函数
function ConstructorCar () {}
ConstructorCar.prototype.drive = function () {
 console.log('Vroom!');
};
const car2 = new ConstructorCar();
console.log(car2.drive());
// 工厂函数
const proto = {
 drive () {
  console.log('Vroom!');
 }
};
function factoryCar () {
 return Object.create(proto);
}
const car3 = factoryCar();
console.log(car3.drive());

這些方法都是基於原型的創建,而且都支援建構時函數中私有變數的實作。換句話說,這些函數擁有著大部分相同的特性,甚至在許多場景下,他們是等價的。

Javascript 中,每個函數都能傳回一個新的物件。當它不是構造函數或類別的時候,它就被稱為工廠函數。

ES6的類別其實是建構函式的語法糖(至少現階段是這樣實行的),所以接下來討論的所有內容都適用於建構函式的也適用於ES6類別:

class Foo {}
console.log(typeof Foo); // function

建構子與ES6類別的好處

  • # 大部分的書會教你去用類別和建構子

  • ‘ this ' 是指向新的這個物件的。

  • 有些人喜歡new 關鍵字的可讀性

  • #也許還會有一些很小的細節方面的差別,但是如果在開發過程中沒有問題的話,也不用太擔心。

# 建構子和ES6類別的壞處

1. 你需要 new 關鍵字

到了ES6,建構子和類別都需要帶 new 關鍵字。

function Foo() {
 if (!(this instanceof Foo)) { return new Foo(); }
}

在ES6中,如果你嘗試呼叫類別函數沒有 new 關鍵字就會拋出一個任務。如果要個不用 new 關鍵字的話,就只能用工廠函數把它包起來。

2. 實例化過程中的細節揭露給了外界API

所有的呼叫都緊緊的關聯到了構造器的實現上,如果你需要自己在構造過程中動一些手腳,那就是一個非常麻煩的事情了。

3. 建構器沒有遵守 Open / Closed 法則

因為 new 關鍵字的細節處理,構造者違反 Open / Closed 法則:API應該開放拓展,避免修改。

我曾經質疑過,類別和工廠函數是那麼的相似,把類別函數升級為一個工廠函數也不會有什麼影響,不過在JavaScript裡面,的確有影響。

如果你開始寫著建構函數或類,但是寫著寫著,你發現需要工廠函數的彈性,這時候你不能簡單的就改改簡單改改函數一走了之。

不幸的是,你是個JavaScript程式設計師,而構造器改造成工廠函數是一個大手術:

// 原来的实现:
// class Car {
//  drive () {
//   console.log('Vroom!');
//  }
// }
// const AutoMaker = { Car };
// 工厂函数改变的实现:
const AutoMaker = {
 Car (bundle) {
  return Object.create(this.bundle[bundle]);
 },
 bundle: {
  premium: {
   drive () {
    console.log('Vrooom!');
   },
   getOptions: function () {
    return ['leather', 'wood', 'pearl'];
   }
  }
 }
};
// 期望中的用法是:
const newCar = AutoMaker.Car('premium');
newCar.drive(); // 'Vrooom!'
// 但是因为他是一个库
// 许多地方依然这样用:
const oldCar = new AutoMaker.Car();
// 如此就会导致:
// TypeError: Cannot read property 'undefined' of
// undefined at new AutoMaker.Car

在上面例子裡面,我們從一個類別開始,最後把它改成來一個可以根據特定的原型來創建物件的工廠函數,這樣的函數可以廣泛應用於介面抽象和特殊需求自訂。

4. 使用建構器讓 instanceof 有可乘之機

# 建構函式和工廠函式的差異就是 instanceof 運算子,很多人使用 instanceof 來確保自己程式碼的正確性。但說實話,這是有很大問題的,建議避免 instanceof 的使用。

instanceof 會說謊。

// instanceof 是一个原型链检查
// 不是一个类型检查
// 这意味着这个检查是取决于执行上下文的,
// 当原型被动态的重新关联,
// 你就会得到这样令人费解的情况
function foo() {}
const bar = { a: 'a'};
foo.prototype = bar;
// bar是一个foo的实例吗,显示不是
console.log(bar instanceof foo); // false
// 上面我们看到了,他的确不是一个foo实例
// baz 显然也不是一个foo的实例,对吧?
const baz = Object.create(bar);
// ...不对.
console.log(baz instanceof foo); // true. oops.

instanceof 並不會像其他強型別語言一樣做檢查,他只是檢查了原型鏈上的物件。

在一些執行上下文中,他就會失效,例如你改變了 Constructor.prototype 的時候。

又比如你開始些的是一個建構函數或類,之後你又將它拓展為一個另一個對象,就像上面改寫成工廠函數的情況。這時候 instanceof 也會有問題。

總而言之, instanceof 是另一個建構函式和工廠函式呼喚的大改變。

用類別的好處

  • 一個方便的,自包含的關鍵字

  • 一個唯一的權威性方法在JavaScript來實作類別。

  • 對於其他有class的語言開發經驗的開發者有很好的體驗。

# 用類別的壞處

構造器所有的壞處, 加上:

# 使用 extends 關鍵字建立一個有問題的類,對於使用者來說是一個很大的誘惑。
類別的層級繼承會造成許多有名的問題,包括 fragile base class(基礎類別會因為繼承而被破壞),gorilla banana problem(物件混雜著複雜的上下文環境),duplication by necessity(類別在繼承多樣化時需要時時修改)等等。

雖然其他兩種方法也有可能讓你陷入這些問題,但是在使用 extend 關鍵字的時候,環境使然,就會把你引導上這條路。換句話說,他引導你向一個不靈活的關係編寫程式碼,而不是更有重複使用性的程式碼。

使用工廠函數的好處

# 工廠函數比起類別和構造函數都更加的靈活,也不會把人引向錯誤的道路。也不會讓你陷入深深的繼承鏈中。你可以用很多手段來模擬繼承

1. 用任意的原型回傳任意的物件

舉個例子,你可以透過同一個實作來建立不同的實例,一個媒體播放器可以針對不同的媒體格式來建立實例,使用不同的API,或是一個事件庫可以是針對DOM時間的或是ws事件。

工廠函數也可以透過執行上下文來實例化對象,可以從物件池中得到好處,也可以更有彈性的繼承模型。

2. 沒有複雜重構的擔憂

# 你永遠不會有把工廠函數轉換成建構函數這樣的需求,所以重構也沒必要。

3. 沒有 new

你不用new關鍵字來新建對象,自己可以掌握這個流程。

4. 標準的 this 行為

# this 就是你熟悉的哪個this,你可以用它來取得父物件。舉例來說,在 player.create() 中,this指向的是player,也可以透過call和apply來綁定其他this。

5. 沒有 instanceof 的煩惱

6. 有些人喜歡直接不帶new的寫法可讀的直覺性。

工廠函數的壞處

  • 並沒有自動的處理原型,工廠函數原型不會波及原型鏈。

  • this 並沒有自動指向工廠函數裡的新物件。

  • 也許還會有一些很小的細節方面的差別,但是如果在開發過程中沒有問題的話,也不用太擔心。

# 結論

在我看來,類別也許是個方便的關鍵字,但也不能掩飾他會把毫無防備的用戶引向繼承深坑。另一個風險在於未來的你想要使用工廠函數的可能性,你要做非常大的改變。

如果你是在一個比較大的團隊協作裡面,如果要修改一個公開的API,你可能幹擾到你並不能接觸到的程式碼,所以你不能對改裝函數的影響視而不見。

工廠模式很棒的一個地方在於,他不僅更加強大,更加靈活,也可以鼓勵整個隊伍來讓API更加簡單,安全,輕便。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

使用nodejs在微信中呼叫收貨地址

keep-alive在vue2中應該怎樣使用

以上是JS的class、建構子、工廠函式使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。