享元模式最適合解決因創建大量類似物件而累及效能的問題,本文將來總結JavaScript設計模式程式設計中的享元模式使用,包括在DOM操作時的利用範例:
享元模式不同於一般的設計模式,它主要用來優化程式的效能,它最適合解決大量類似的物件而產生的效能問題。享元模式透過分析應用程式的對象,將其解析為內在數據和外在數據,減少對象的數量,從而提高應用程式的效能。
基本知識
享元模式透過共享大量的細粒度的對象,減少對象的數量,從而減少對象的內存,提高應用程式的效能。其基本思想就是分解現有類似對象的組成,將其展開為可以共享的內在數據和不可共享的外在數據,我們稱內在數據的對象為享元對象。通常還需要一個工廠類別來維護內在資料。
在JS中,享元模式主要有下面幾個角色組成:
(1)客戶端:用來呼叫享元工廠來取得內在資料的類,通常是應用程式所需的對象,
(2)享元工廠:用來維護享元資料的類別
(3)享元類別:保持內在資料的類別
享元模式的實作與應用
一般實作
我們舉個例子來說明:蘋果公司大量生產iphone,iphone的大部分數據例如型號,螢幕都是一樣,少數部分數據例如記憶體有分16G,32G等。未使用享元模式前,我們寫程式碼如下:
function Iphone(model, screen, memory, SN) { this. model = model; this.screen = screen; this.memory = memory; this.SN = SN; } var phones = []; for (var i = 0; i < 1000000; i++) { var memory = i % 2 == 0 ? 16 : 32; phones.push(new Iphone("iphone6s", 5.0, memory, i)); }
#這段程式碼中,創建了一百萬個iphone,每個iphone都獨立申請一個記憶體。但是我們仔細觀察可以看到,大部分iphone都是類似的,只是記憶體和序號不一樣,如果是一個對效能要求比較高的程序,我們就要考慮去優化它。
大量相似物件的程序,我們就可以考慮用享元模式去優化它,我們分析出大部分的iphone的型號,屏幕,內存都是一樣的,那這部分數據就可以公用,就是享元模式中的內在數據,定義享元類如下:
function IphoneFlyweight(model, screen, memory) { this.model = model; this.screen = screen; this.memory = memory; }
我們定義了iphone的享元類,其中包含型號,螢幕和記憶體三個數據。我們還需要一個享元工廠來維護這些資料:
var flyweightFactory = (function () { var iphones = {}; return { get: function (model, screen, memory) { var key = model + screen + memory; if (!iphones[key]) { iphones[key] = new IphoneFlyweight(model, screen, memory); } return iphones[key]; } }; })();
在這個工廠中,我們定義了一個字典來保存享元對象,提供一個方法根據參數來取得享元對象,如果字典中有則直接返回,沒有則建立一個返回。
接著我們建立一個客戶端類,這個客戶端類別就是修改自iphone類:
function Iphone(model, screen, memory, SN) { this.flyweight = flyweightFactory.get(model, screen, memory); this.SN = SN; }
然後我們依舊像之間那樣產生多個iphone
var phones = []; for (var i = 0; i < 1000000; i++) { var memory = i % 2 == 0 ? 16 : 32; phones.push(new Iphone("iphone6s", 5.0, memory, i)); } console.log(phones);
這裡的關鍵就在於Iphone建構子裡面的this.flyweight = flyweightFactory.get(model, screen, memory)。這句程式碼透過享元工廠去獲取享元數據,而在享元工廠裡面,如果已經存在相同數據的對象則會直接返回對象,多個iphone對象共享這部分相同的數據,所以原本類似的數據已經大大減少,減少的記憶體的佔用。
享元模式在DOM中的應用
享元模式的一個典型應用就是DOM事件操作,DOM事件機制分成事件冒泡和事件擷取。我們簡單介紹一下這兩者:
事件冒泡:綁定的事件從最裡層的元素開始觸發,然後冒泡到最外層
事件捕獲:綁定的事件從最外層的元素開始觸發,然後傳到最裡層
假設我們HTML中有一個選單清單
<ul class="menu"> <li class="item">选项1</li> <li class="item">选项2</li> <li class="item">选项3</li> <li class="item">选项4</li> <li class="item">选项5</li> <li class="item">选项6</li> </ul>
點擊選單項,進行對應的動作,我們透過jQuery來綁定事件,一般會這麼做:
$(".item").on("click", function () { console.log($(this).text()); })
#給每個清單項目綁定事件,點選輸出對應的文字。這樣看暫時沒有什麼問題,但是如果是一個很長的列表,尤其是在行動端特別長的列表時,就會有效能問題,因為每個項目都綁定了事件,都佔用了記憶體。但這些事件處理程序其實都是很類似的,我們就要對其進行最佳化。
$(".menu").on("click", ".item", function () { console.log($(this).text()); })
透過這種方式進行事件綁定,可以減少事件處理程序的數量,這種方式叫做事件委託,也是運用了享元模式的原理。事件處理程序是公用的內在部分,每個選單項目各自的文字就是外在部分。我們簡單說下事件委託的原理:點選選單項,事件會從li元素冒泡到ul元素,我們綁定事件到ul上,實際上就綁定了一個事件,然後透過事件參數event裡面的target來判斷點擊的具體是哪一個元素,例如低階第一個li元素,event.target就是li,這樣就能拿到具體的點擊元素了,就可以根據不同元素進行不同的處理。
總結
#享元模式是一種最佳化程式效能的手段,透過共享公用資料來減少物件數量以達到最佳化程式的手段。享元模式適用於擁有大量類似物件並且對效能有要求的場景。因為享元模式需要分離內部和外部數據,增加了程式的邏輯複雜性,建議對效能有要求的時候才使用享元模式。
享元模式之利:
可以把網頁的資源符合降低幾個數量級。即使享元模式的應用無法將實例的數量削減到一個,你仍能夠從中獲益不少。
這種節省不需要大量修改原有程式碼。在創建了管理器、工廠和享元之後,就需要對程式碼進行的修改只不過是從直接實例化目標類別改為呼叫管理器物件的某個方法。
享元模式之弊:
如果把它用在不必要的地方,其結果反而有損程式碼的運作效率。這種模式在優化程式碼的同時,也提高了其複雜程度,這會對調試和維護造成困難。
它之所以會妨礙調試,是因為現在可能出錯的地方變成了三個:管理器、工廠和享元。
這種最佳化也會使維護變得更加困難。現在你面對的不是由封裝著資料的物件構成的清晰架構,而是一堆又碎又亂的東西。其中的數據至少分兩處保存。最好註釋標明內在資料和外在資料。
只有在必要的時候才應該進行這種最佳化。必須在運作效率和可維護性之間進行權衡。如果拿不準是否需要使用享元模式,那麼你很可能並不需要它。享元模式適合的是系統資源已經用得差不多而且明顯需要進行某種優化這樣一類場合。
這個模式對Javascript程式設計師特別有用,因為它可以用來減少網頁上所要使用的DOM元素的數量,要知道這些元素需要耗費許多記憶體。結合使用這種模式與組合模式等組織型可以開發出功能豐富的複雜Web應用系統,它們可以平穩的運作在任何現代Javascript環境中。
享元模式的適用場合:
網頁中必須使用了大量資源密集型物件。如果只會用到少許這類對象,這種優化並不划算。
物件中所保存的資料至少有一部分能被轉換為外在資料。此外,將這些資料儲存在物件外部所佔用的資源應該相對較少,否則這種做法對於效能的提示實際上毫無意義。那種大量包含基礎性程式碼和HTML內容的物件可能比較適合這種最佳化。
將外在資料分開後,獨一無二的物件的數目相對較少。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
#對javascript Function函數深入理解與實戰(附上程式碼)
#
以上是詳細解讀在JavaScript設計模式程式設計中的享元模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

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

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

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

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

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

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

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

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

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!