搜尋
首頁web前端js教程在Javascript中的有關class、建構函式、工廠函數的使用方法

這篇文章主要介紹了詳解Javascript 中的class、建構函數、工廠函數,需要的朋友可以參考下

到了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更加簡單,安全,輕便。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

在nodejs中如何實作websocket通訊功能

微信小程式如何實作塗鴉

#詳細解讀在React元件「外」如何使用父元件

#詳細解讀ES6語法中可迭代協定

#

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

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

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

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具