最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

輕松掌握JavaScript享元模式

 更新時間:2016年08月27日 08:48:44   作者:蘇福  
這篇文章主要幫助大家輕松掌握JavaScript享元模式,告訴大家想什么是js享元模式,感興趣的小伙伴們可以參考一下

在JavaScript中,瀏覽器特別是移動端的瀏覽器分配的內存很有限,如何節(jié)省內存就成了一件非常有意義的事情。節(jié)省內存的一個有效方法是減少對象的數(shù)量。 

享元模式(Flyweight),運行共享技術有效地支持大量細粒度的對象,避免大量擁有相同內容的小類的開銷(如耗費內存),使大家共享一個類(元類)。 

享元模式可以避免大量非常相似類的開銷,在程序設計中,有時需要生產大量細粒度的類實例來表示數(shù)據(jù),如果能發(fā)現(xiàn)這些實例除了幾個參數(shù)以外,開銷基本相同的話,就可以大幅度較少需要實例化的類的數(shù)量。如果能把那些參數(shù)移動到類實例的外面,在方法調用的時候將他們傳遞進來,就可以通過共享大幅度第減少單個實例 的數(shù)目。 

在JavaScript中應用享元模式有兩種方式,第一種是應用在數(shù)據(jù)層上,主要是應用在內存里大量相似的對象上;第二種是應用在DOM層上,享元可以用在中央事件管理器上用來避免給父容器里的每個子元素都附加事件句柄 

Flyweight中有兩個重要概念--內部狀態(tài)intrinsic和外部狀態(tài)extrinsic之分,內部狀態(tài)就是在對象里通過內部方法管理,而外部信息可以在通過外部刪除或者保存。 

說白點,就是先捏一個的原始模型,然后隨著不同場合和環(huán)境,再產生各具特征的具體模型,很顯然,在這里需要產生不同的新對象,所以Flyweight模式中常出現(xiàn)Factory模式,F(xiàn)lyweight的內部狀態(tài)是用來共享的,F(xiàn)lyweight factory負責維護一個Flyweight pool(模式池)來存放內部狀態(tài)的對象。 

我們可以將內部狀態(tài)相同的所有對象替換為同一個共享對象,而要創(chuàng)建這樣一個共享對象就需要用到單例工廠方法,而不是普通的構造函數(shù),這樣做可以跟蹤到已經實例化的各個對象,從而僅當所需對象的內部狀態(tài)不同于已有對象時才創(chuàng)建一個新對象。對象的外在狀態(tài)被保存在一個管理器對象中。在調用對象的方法時,管理器會把這些外在狀態(tài)作為參數(shù)傳入。 

把一個對象的數(shù)據(jù)保存在兩個不同的對象中(共享對象、管理器對象)
 1.共享對象(享元對象)
 2.單例工廠方法(創(chuàng)建共享對象)
 3.管理器對象(管理外部狀態(tài)) 

比如圖書館中的一本書可以用一個對象來表示,他有很多屬性

 var Book = function( id, title, author, genre, pageCount,publisherID, ISBN, checkoutDate, checkoutMember, dueReturnDate,availability ){
  ...//初始化代碼
}
Book.prototype = {
  getTitle:function(){
    return this.title;
  },
  ...
  // 更新借出狀態(tài)方法
  updateCheckoutStatus:function(bookID, newStatus, checkoutDate,checkoutMember, newReturnDate){...},
  //續(xù)借
  extendCheckoutPeriod: function(bookID, newReturnDate){...},
  //是否到期
  isPastDue: function(bookID){...}
} 

程序剛開始可能沒問題,但是隨著時間的增加,圖書可能大批量增加,并且每種圖書都有不同的版本和數(shù)量,你將會發(fā)現(xiàn)系統(tǒng)變得越來越慢。幾千個book對象在內存里可想而知,我們需要用享元模式來優(yōu)化。 

我們可以將數(shù)據(jù)分成內部和外部兩種數(shù)據(jù),同一本書中,和book對象相關的數(shù)據(jù)(title,author等)可以歸結為內部屬性,而(checkoutMember,dueReturnDate等)可以歸結為外部屬性。這樣,如下代碼就可以在同一本書里共享同一個對象了,因為不管誰借的書,只要書是同一本書,基本信息是一樣的:

 //共享對象
var Book = function(title, author, genre, pageCount, publisherID, ISBN){
  this.title = title;
  this.author = author;
  this.genre = genre;
  this.pageCount = pageCount;
  this.publisherID = publisherID;
  this.ISBN = ISBN;
}; 

讓我們來定義一個基本工廠,用來檢查之前是否創(chuàng)建該book的對象,如果有就返回,沒有就重新創(chuàng)建并存儲以便后面可以繼續(xù)訪問,這確保我們?yōu)槊恳环N書只創(chuàng)建一個對象:

 /* Book工廠 單例 */
var BookFactory = (function(){
  var existingBooks = {};
  return{
    createBook: function(title, author, genre,pageCount,publisherID,ISBN){
    /*查找之前是否創(chuàng)建*/
      var existingBook = existingBooks[ISBN];
      if(existingBook){
        return existingBook;
      }else{
        /* 如果沒有,就創(chuàng)建一個,然后保存*/
        var book = new Book(title, author, genre,pageCount,publisherID,ISBN);
        existingBooks[ISBN] = book;
        return book;
      }
    }
  }
}); 

外部狀態(tài),相對就簡單了,除了我們封裝好的book,其它都需要在這里管理:

 /*BookRecordManager 借書管理類 單例*/
var BookRecordManager = (function(){
  var bookRecordDatabase = {};
  return{
    /*添加借書記錄*/
    addBookRecord: function(id, title, author, genre,pageCount,publisherID,ISBN, checkoutDate, checkoutMember, dueReturnDate, availability){
      var book = bookFactory.createBook(title, author, genre,pageCount,publisherID,ISBN);
      bookRecordDatabase[id] ={
        checkoutMember: checkoutMember,
        checkoutDate: checkoutDate,
        dueReturnDate: dueReturnDate,
        availability: availability,
        book: book;
      };
    },
    updateCheckoutStatus: function(bookID, newStatus, checkoutDate, checkoutMember, newReturnDate){
      var record = bookRecordDatabase[bookID];
      record.availability = newStatus;
      record.checkoutDate = checkoutDate;
      record.checkoutMember = checkoutMember;
      record.dueReturnDate = newReturnDate;
    },
    extendCheckoutPeriod: function(bookID, newReturnDate){
      bookRecordDatabase[bookID].dueReturnDate = newReturnDate;
    },
    isPastDue: function(bookID){
      var currentDate = new Date();
      return currentDate.getTime() > Date.parse(bookRecordDatabase[bookID].dueReturnDate);
    }
  };
}); 

通過這種方式,我們做到了將同一種圖書的相同信息保存在一個bookmanager對象里,而且只保存一份;相比之前的代碼,就可以發(fā)現(xiàn)節(jié)約了很多內存。 

對象池 
對象池是另外一種性能優(yōu)化方案,和享元模式有一些相似之處,但沒有分離內部狀態(tài)和外部狀態(tài)這個過程。 
通用對象池實現(xiàn):

 var objectPoolFactory = function (createObjFn) {
  var objectPool = []; //對象池
  return {
    create: function () { //取出
      var obj = objectPool.length === 0 ? createObjFn.apply(this,arguments) : objectPool.shift();
      return obj;
    },
    recover: function (obj) { //收回
      objectPool.push(obj);
    }
  }
}; 

現(xiàn)在利用objectPoolFactory來創(chuàng)建一個裝載一些iframe的對象池:

 var iframeFactory = objectPoolFactory(function () {
  var iframe = document.createElement('iframe');
  document.body.appendChild(iframe);
  iframe.onload = function () {
    iframe.onload = null; //防止iframe重復加載的bug
    iframeFactory.recover(iframe); //iframe加載完成后往對象池填回節(jié)點(收回)
  };
  return iframe;
});
//調用
var iframe1 = iframeFactory.create();
iframe1.src = 'http://www.qq.com'; 

參考文獻: 《JavaScript模式》 《JavaScript設計模式與開發(fā)實踐》

 以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • js父頁面中使用子頁面的方法

    js父頁面中使用子頁面的方法

    這篇文章主要向大家介紹了js父頁面中使用子頁面的方法,即js父頁面使用iframe中的函數(shù),感興趣的朋友可以參考一下
    2016-01-01
  • JavaScript數(shù)據(jù)類型檢測實現(xiàn)方法詳解

    JavaScript數(shù)據(jù)類型檢測實現(xiàn)方法詳解

    Javascript中檢查數(shù)據(jù)類型一直是老生常談的問題,類型判斷在web開發(fā)中也有著非常廣泛的應用,所以下面這篇文章主要給大家介紹了關于JS數(shù)據(jù)類型檢測的那些事,需要的朋友可以參考下
    2022-11-11
  • intro.js 頁面引導簡單用法 分享

    intro.js 頁面引導簡單用法 分享

    這篇文章介紹了intro.js 頁面引導簡單用法,有需要的朋友可以參考一下
    2013-08-08
  • 微信小程序實現(xiàn)點擊圖片放大預覽

    微信小程序實現(xiàn)點擊圖片放大預覽

    這篇文章主要為大家詳細介紹了小程序實現(xiàn)點擊圖片放大預覽功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • JavaScript實現(xiàn)學生在線做題計時器功能

    JavaScript實現(xiàn)學生在線做題計時器功能

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)學生在線做題計時器功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • JavaScript使用鏈式方法封裝jQuery中CSS()方法示例

    JavaScript使用鏈式方法封裝jQuery中CSS()方法示例

    這篇文章主要介紹了JavaScript使用鏈式方法封裝jQuery中CSS()方法,結合具體實例形式分析了JS采用鏈式操作方法封住jQuery中連綴操作實現(xiàn)css()方法的相關技巧,需要的朋友可以參考下
    2017-04-04
  • 純文字版返回頂端的js代碼

    純文字版返回頂端的js代碼

    這篇文章介紹了純文字版返回頂端的js代碼,有需要的朋友可以參考一下
    2013-08-08
  • js事件源window.event.srcElement兼容性寫法(詳解)

    js事件源window.event.srcElement兼容性寫法(詳解)

    下面小編就為大家?guī)硪黄猨s事件源window.event.srcElement兼容性寫法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • js裁剪(分隔)字符串的三種常用方法

    js裁剪(分隔)字符串的三種常用方法

    在開發(fā)中我們經常會遇到對于字符串的部分取舍問題,本文主要介紹了js裁剪(分隔)字符串的三種常用方法,今天我們來看看3中常用的方法來解決這個問題,感興趣的可以一起了解一下
    2022-02-02
  • JavaScript中實現(xiàn)繼承的三種方式和實例

    JavaScript中實現(xiàn)繼承的三種方式和實例

    這篇文章主要介紹了JavaScript中實現(xiàn)繼承的三種方式和實例,本文講解了類式繼承、原型式繼承、使用擴充方法實現(xiàn)多重繼承三種方式,需要的朋友可以參考下
    2015-01-01

最新評論

华池县| 东莞市| 腾冲县| 冷水江市| 开封县| 陕西省| 怀安县| 海伦市| 合水县| 治县。| 蒙阴县| 合川市| 宜宾县| 乐昌市| 永春县| 澄城县| 双牌县| 新宁县| 郎溪县| 襄樊市| 德惠市| 丹东市| 汝南县| 锡林郭勒盟| 井冈山市| 庆阳市| 紫云| 辉南县| 西平县| 时尚| 武冈市| 万州区| 南宫市| 巴楚县| 木兰县| 武邑县| 曲沃县| 陵川县| 防城港市| 西吉县| 祁东县|