目錄
物件字面量
工廠函數
原型鏈
ES6 類別
比較
效能
特點
結論
首頁 web前端 js教程 JavaScript 建立物件模式與最佳實踐的程式碼實例詳解

JavaScript 建立物件模式與最佳實踐的程式碼實例詳解

Mar 07, 2017 pm 02:41 PM

在JavaScript中「建立物件」是一個複雜的話題。這門語言提供了許多創造物件的方式,不論新手或老手都可能對此感到無所適從,不知道該選擇哪一種。不過,儘管創建物件的方法很多,看起來語法差異也很大,但實際上它們的相似性可能比你所以為的要多。本文將帶領你踏上一段梳理物件創建方法的旅程,為你揭示不同方法之間的依賴與遞進關係。

物件字面量

我們的第一站毫無疑問就是創建物件最簡單的方法,物件字面量。 JavaScript總是宣揚自己能夠「無中生有」地創造物件——不需要類別、不需要模板、不需要原型——「噌」地一下,一個有方法有資料的物件就出現了。

var o = {
  x: 42,
  y: 3.14,
  f: function() {},
  g: function() {}
};
登入後複製

但這種方法有一個缺點:如果我們想在其他地方創建一個同類型的對象,就得把這個對象的方法、資料和初始化都複製貼上過去。我們需要一種能夠批量創建同類型物件的方法,而不是只創建一個物件。

工廠函數

我們的下一站是工廠函數。顯然,用這種方法來建立一類具有相同結構、介面和實作的物件是最簡單的。我們不直接建立一個物件字面量,而是將物件字面量作為函數的回傳值,當我們需要多次或多處建立同類型的物件時,只要呼叫這個函數就行了。

function thing() {
  return {
    x: 42,
    y: 3.14,
    f: function() {},
    g: function() {}
  };
}

var o = thing();
登入後複製

但這種方法也有一個缺點:它會導致記憶體膨脹,因為每個物件都包含了工廠函數的獨立副本。理論上我們希望所有物件共享一個工廠函數副本。

原型鏈

JavaScript提供了一個內建的在物件之間共享資料的機制,稱為原型鏈。當我們存取一個物件的屬性時,它會委託某些其他物件來完成這項請求。我們可以利用這一點來修改工廠函數,使它創建的每個物件只包含自己特有的數據,而對其他屬性的請求則全部委託給原型鏈上共有的一個物件。

var thingPrototype = {
  f: function() {},
  g: function() {}
};

function thing() {
  var o = Object.create(thingPrototype);

  o.x = 42;
  o.y = 3.14;

  return o;
}

var o = thing();
登入後複製

事實上,JavaScript本身就有內建的機制來支援這種通用模式。我們不需要自己創建這個共有的對象(即原型對象),JavaScript會自動為每個函數創建一個原型對象,我們可以把共享資料直接放在這個對象裡。

thing.prototype.f = function() {};
thing.prototype.g = function() {};

function thing() {
  var o = Object.create(thing.prototype);

  o.x = 42;
  o.y = 3.14;

  return o;
}

var o = thing();
登入後複製

但這種方法也有一個缺點:會導致重複。上述thing函數的第一行和最後一行在每一個「委託原型的工廠函數」中都會重複一次,幾乎沒有差別。

ES5 類別

我們可以把那些重複的程式碼抽出來,放進一個自訂函數裡。這個函數會建立一個對象,並與其他某個任意函數(參數函數)的原型建立委託(繼承)關係,然後我們把新建立的物件當作參數,呼叫這個函數(參數函數),最後返回這個新的對象。

function create(fn) {
  var o = Object.create(fn.prototype);

  fn.call(o);

  return o;
}

// ...

Thing.prototype.f = function() {};
Thing.prototype.g = function() {};

function Thing() {
  this.x = 42;
  this.y = 3.14;
}

var o = create(Thing);
登入後複製

事實上,JavaScript對此方法也有內建的支援機制。我們定義的這個create函數其實就是new關鍵字的一個基本實現,因此我們可以順手把create換成new。

Thing.prototype.f = function() {};
Thing.prototype.g = function() {};

function Thing() {
  this.x = 42;
  this.y = 3.14;
}

var o = new Thing();
登入後複製

我們現在抵達的這一站通常被稱為ES5類。它透過函數來創建對象,把需要共享的資料委託給原型對象,並使用new關鍵字來處理重複的邏輯。

但這種方法也有一個缺點:冗長又難看,實現繼承的時候會更冗長更難看。

ES6 類別

JavaScript最新的相關改進是ES6 類,用新語法來實現上述功能要簡潔得多。

class Thing {
  constructor() {
    this.x = 42;
    this.y = 3.14;
  }

  f() {}
  g() {}
}

var o = new Thing();
登入後複製

比較

多年來,JavaScript開發者們與原型鏈的關係總是若即若離,糾纏不清。而今天我們最有可能遇到的兩種創建物件的方式,一種是強烈依賴原型鏈的class語法,另一種則是完全不依賴原型鏈的工廠函數語法。這兩種方式在性能上和特點上是不一樣的——儘管差異不太大。

效能

今天的JavaScript引擎已經經過了大幅的最佳化,以至於很難透過JavaScript程式碼來推斷怎麼會比較快。關鍵在於測量方法。然而測量方法有時也會失靈。通常每六週就會有更新的JavaScript引擎發布,而在這之前採取的測量方法,和基於這種測量方法所做的決策都有可能失去意義。因此,我的經驗法則是選擇最官方、最廣泛使用的語法,因為大多數時候它經歷的實踐檢驗最多,因而性能是最高的。目前來說class語法最符合這一點,寫這篇文章時,class語法大約比回傳字面量的工廠函數快3倍。

特點

隨著ES6的發布,類別與工廠函數之間曾經存在的幾點差異消失了。現在,工廠函數和類別都能夠強制實現真正的私有資料-工廠函數透過閉包實現,類別透過WeakMap實現。兩者都能實現多重繼承——工廠函數可以將其他屬性混入自己的對象,類別也可以將其他屬性混入自己的原型,或者透過類別工廠,透過代理也能實現。工廠函數和類別也都可以在需要的時候傳回任意對象,語法也都很簡單。

結論

綜合考慮,我比較傾向class文法。它標準、簡單、乾淨、快速,也提供了所有曾經只有函數工廠才具備的特質。

以上就是JavaScript 創建物件模式與最佳實踐的程式碼實例詳解的內容,更多相關內容請關注PHP中文網(www.php.cn)!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP中處理字串轉浮點數的最​​佳實踐 PHP中處理字串轉浮點數的最​​佳實踐 Mar 28, 2024 am 08:18 AM

在PHP中處理字串轉浮點數是開發過程中常見的需求,例如從資料庫讀取到的金額欄位是字串類型,需要轉換為浮點數進行數值計算。在這篇文章中,我們將介紹PHP中處理字串轉浮點數的最​​佳實踐,並給出具體的程式碼範例。首先,我們需要明確一點,PHP中的字串轉浮點數有兩種主要的方式:使用(float)型別轉換或使用(floatval)函數。下面我們將分別來介紹這兩

Golang中字符串拼接的最佳實踐是什麼? Golang中字符串拼接的最佳實踐是什麼? Mar 14, 2024 am 08:39 AM

Golang中字符串拼接的最佳实践是什么?在Golang中,字符串拼接是一种常见的操作,但是要考虑到效率和性能。在处理大量字符串拼接时,选择合适的方法可以显著提升程序的性能。下面将介绍几种Golang中字符串拼接的最佳实践,并附上具体的代码示例。使用strings包的Join函数在Golang中,使用strings包的Join函数是一种高效的字符串拼接方法。

探討在Go語言中縮排的最佳實踐 探討在Go語言中縮排的最佳實踐 Mar 21, 2024 pm 06:48 PM

在Go語言中,良好的縮排是程式碼可讀性的關鍵。在編寫程式碼時,統一的縮排風格能夠使程式碼更加清晰、易於理解。本文將探討在Go語言中縮排的最佳實踐,並提供具體的程式碼範例。使用空格而不是製表符在Go語言中,建議使用空格而不是製表符進行縮排。這樣可以避免不同編輯器中製表符寬度不一致所導致的排版問題。縮排的空格數Go語言官方建議使用4個空格作為縮排的空格數。這樣可以使程式碼在

golang框架有哪些最佳實踐 golang框架有哪些最佳實踐 Jun 01, 2024 am 10:30 AM

在使用Go框架時,最佳實踐包括:選擇輕量級框架,如Gin或Echo。遵循RESTful原則,使用標準HTTP動詞和格式。利用中間件簡化任務,如身份驗證和日誌記錄。正確處理錯誤,使用錯誤類型和有意義的訊息。編寫單元測試和整合測試,確保應用程式正常運作。

深入比較:Java框架與其他語言框架的最佳實踐 深入比較:Java框架與其他語言框架的最佳實踐 Jun 04, 2024 pm 07:51 PM

Java框架適用於跨平台、穩定性和可擴展性至關重要的專案。對於Java項目,SpringFramework用於依賴注入和麵向方面編程,最佳實踐包括使用SpringBean和SpringBeanFactory。 Hibernate用於物件關係映射,最佳實踐是使用HQL進行複雜查詢。 JakartaEE用於企業應用開發,最佳實踐是使用EJB進行分散式業務邏輯。

PHP最佳實踐:避免goto語句的替代方案探討 PHP最佳實踐:避免goto語句的替代方案探討 Mar 28, 2024 pm 04:57 PM

PHP最佳實踐:避免goto語句的替代方案探討在PHP程式設計中,goto語句是一種控制結構,它允許直接跳到程式中的另一個位置。雖然goto語句可以簡化程式碼結構和流程控制,但由於其使用容易導致程式碼混亂、可讀性降低以及除錯困難等問題,因此被廣泛認為是一種不良實踐。在實際開發中,為避免使用goto語句,我們需要尋找替代方法來實現相同的功能。本文將探討一些替代方案,

Laravel開發中.env檔的作用及最佳實踐 Laravel開發中.env檔的作用及最佳實踐 Mar 10, 2024 pm 03:03 PM

Laravel開發中.env文件的作用及最佳實踐在Laravel應用程式開發中,.env文件被認為是非常重要的文件之一。它承載著一些關鍵的配置訊息,例如資料庫連接資訊、應用程式環境、應用程式金鑰等。在本文中,我們將深入探討.env檔案的作用以及最佳實踐,並附上具體的程式碼範例。 1..env檔的作用首先,我們需要了解.env檔的作用。在一個Laravel應

Git 還是版本控制? PHP 專案管理中的關鍵區別 Git 還是版本控制? PHP 專案管理中的關鍵區別 Mar 10, 2024 pm 01:04 PM

版本控制:基礎版本控制是一種軟體開發實踐,允許團隊追蹤程式碼庫中的變更。它提供了一個中央儲存庫,其中包含專案文件的所有歷史版本。這使開發人員能夠輕鬆回滾錯誤,查看不同版本的差異,並協調對程式碼庫的並發變更。 Git:分散式版本控制系統git是一種分散式版本控制系統(DVCS),這表示每個開發人員的電腦都擁有整個程式碼庫的完整副本。這消除了對中心伺服器的依賴,提高了團隊的靈活性和協作能力。 Git允許開發人員建立和管理分支,追蹤程式碼庫的歷史,並與其他開發者共用變更。 Git與版本控制:關鍵區別分散式vs集

See all articles