JavaScript面向對象輕鬆入門之綜合

来源:http://www.cnblogs.com/elonhu/archive/2017/12/15/8044602.html
-Advertisement-
Play Games

javascrpit面向對象之綜合 這一章是對前幾章的一個總結,通過一個案例來綜合認識javascript面向對象的基本用法 需求: 幾乎所有的web應用都需要保存數據一些到本地,那麼我們就來做一個數據儲存器吧。 詳細需求需求: 當本地儲存有數據時,取用本地的數據,沒有時使用預設的數據 判斷本地的數 ...


javascrpit面向對象之綜合     這一章是對前幾章的一個總結,通過一個案例來綜合認識javascript面向對象的基本用法   需求:   幾乎所有的web應用都需要保存數據一些到本地,那麼我們就來做一個數據儲存器吧。 詳細需求需求:   當本地儲存有數據時,取用本地的數據,沒有時使用預設的數據   判斷本地的數據是否過時,如果過時則不使用   預設使用localStorage,但支持使用其它儲存方式,並且要支持多方儲存,多方讀取

 

抽象出對象 根據需求裡面的關鍵字,我們抽象出三個對象:數據訪問、數據、儲存器   數據儲存管理器負責管理數據,對外暴露介面   數據對象負責對數據的操作   儲存器負責保持數據,讀取數據 儲存器對象   DataStorageManagerBase暴露兩個介面save()和load(),模擬抽象類,告訴子類一定要實現這兩個方法。   下麵的例子用LocalStorage實現了一個子類,當然你也可以用cookie或其它方式實現。   為什麼要把LocalStorage這些儲存器進行二次封裝呢?直接用不就可以了嗎?   因為各種儲存器等api都是不一樣等,我們二次封裝後可以確保無論什麼儲存器對外暴露的介面都是save()和load()。
/*模擬數據儲存器抽象類,其實這個類不要也可以*/
class DataStorageManagerBase {
    static getIns() {
        /* 儲存器在整個應用的生命周期里應該只有一個實例 */
        if (!this._ins) this._ins = new this();
        return this._ins;
    }
    constructor() {
        this.name = null;
    }
    save(name/* string */, data/* any */) {
        throw '"' + this.constructor.name + "'類沒有save()方法";
    }
    load(name/* string */) {
        throw '"' + this.constructor.name + "'類沒有load()方法";
    }
}
class LocalStorageManager extends DataStorageManagerBase {
    static getIns() {
        /* 靜態方法不能繼承 */
        if (!this._ins) this._ins = new this();
        return this._ins;
    }
    constructor() {
        super();
        this.name = 'localStorage';
    }
    save(name/* string */, data/* any */) {
        console.log(name,data)
        if (!window.localStorage) return this;//判斷這個儲存器可用不可用,你也可以在這裡拋出錯誤
        window.localStorage[name] = JSON.stringify(data);
        return this;
    }
    load(name/* string */) {
        //如果儲存器不可用,返回false
        if (!window.localStorage) return false;
        //如果沒有這個數據,返回false
        if (!window.localStorage[name]) return false;
        let dataLoaded = JSON.parse(window.localStorage[name]);
        return dataLoaded;
    }
}
數據對象   對數據的操作:保存、讀取、判斷版本等
class GlobalData {
    static addStorage(storage/* DataStorageManagerBase */) {
        /*動態添加儲存器*/
        this._storages.push();
    }
    static getStorages() {
        return this._storages;
    }
    constructor(name, data, version) {
        this.name = name;
        this.data = data;
        this.version = version || 1;
        this._loadData();
        //初始化的該對象的時候,讀取localStorage里的數據,看有沒有已儲存的數據,有就用該數據
    }
    getData() {
        return this._copy(this.data);
    }
    setData(data, notSave) {
        this.data = this._copy(data);
        if (!!notSave) return this;
        let dataToSave = {
            name: this.name,
            version: this.version,
            data: this.data
        };
        let storages = GlobalData.getStorages();
        for (let i = 0, l = storages.length; i < l; i++) {
            /*輪詢所有儲存器,把數據保存在這些儲存器中*/
            storages[i].save(this.name,dataToSave);
        }
        return this;
    }
    _copy(data) {
        /*深拷貝*/
        if (typeof data != "object") return data;
        return JSON.parse(JSON.stringify(data));
    }
    _loadData() {
        let storages = GlobalData.getStorages();
        for (let i = 0, l = storages.length; i < l; i++) {
            /*輪詢所有儲存器,依次獲取數據*/
            const dataLoaded = storages[i].load(this.name);
            if(!!dataLoaded) {
                this._updateData(dataLoaded);
                return;
            }
        }
    }
    _updateData(dataLoaded) {
        if (dataLoaded.version < this.version) return this;
        this.data = dataLoaded.data;
        return this;
    }
}
GlobalData._storages = [LocalStorageManager.getIns()];// 預設添加LocalStorageManager儲存器
數據訪問對象 對數據對象管理,對外暴露三個介面getData(),setData(),config(),用戶通過這三個介面使用這個模塊
class GlobalDataDao {
    static getIns() {
        if (!this._ins) this._ins = new this();
        return this._ins;
    }
    constructor() {
        this.GlobalDataClass = GlobalData;
        this._dataList = [];
    }
    getData(name/* string */) {
        let dataIns = this.getDataIns(name);
        if (!!dataIns) {
            return dataIns.getData();
        } else {
            return null;
        }
    }
    setData(name/* string */, data/* any */, notSave = false/* ?boolean */) {
        let dataIns = this.getDataIns(name);
        dataIns.setData(data, notSave);
        return this;
    }
    config(configs/* Array<Config> */) {
        /* 初始化數據
        interface Config {
            name: string;
            data; any;
            version?: number;
        }
        */
        for (let i in configs) {
            let de = configs[i];
            if (!!this.getDataIns(de.name)) {
                /* 如果數據名重覆,拋出錯誤 */
                throw new Error('data name "' + de.name + '" is exist');
            };
            let dataIns = new GlobalData(de.name, de.data, de.version);
            this._dataList.push(dataIns);
        }
        return this;
    }
    getDataIns(name/* string */) {
        for (let i in this._dataList) {
            if (this._dataList[i].name === name) {
                return this._dataList[i];
            }
        }
        return false;
    }
}

使用

/*用法*/
let globalDataManeger = GlobalDataDao.getIns();

let configs = [
    {
        name: 'languageUsing',
        version: 1,
        data: {
            name: '簡體中文',
            value: 'zh-cn'
        }
    }, {
        name: 'userPreference',
        version: 1,
        data: {
            theme: 'blue',
            menu: 'side_bar'
        }
    }
];
globalDataManeger.config(configs);
console.log(globalDataManeger);
let languageUsing = globalDataManeger.getData('languageUsing');
console.log(languageUsing);
languageUsing.name = 'English';
languageUsing.value = 'en';
globalDataManeger.setData('languageUsing', languageUsing);

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於本例單入口時打包的文件體積過大,將其分成多入口。 主要涉及到的幾個文件為: /index.html, /webpack.dll.config.js, /build/webpack.base.conf.js, /build/webpack.dev.conf.js, /build/webpack.p ...
  • 1、數據方法分類: (1)原數組改變 push pop unshift shift reverse sort splice (2)原數組未變,生成新數組 slice concat filter 對於使原數組變化的方法,可以直接更新視圖。 對於原數組未變的方法,可以使用新數組替換原來的數組,以使視圖發 ...
  • 如果直接在綁定的函數中傳入this,則不能正確獲取,且不能獲取到相關的inputfile對象 ...
  • Lazy Load也叫惰性載入,延遲載入,顧名思義,就是在圖片未到達可視區域時,不載入圖片,我們常常在很多的優秀網站上看到類似的例子,例如迅雷、土豆、優酷等,由於一個網頁的圖片非常多,一次性載入增加伺服器壓力,而且用戶未必會拉到底部,浪費用戶流量,Lazy Load採用按需載入,更快的載入速度從而達 ...
  • 【學習實踐用】 後臺:nodejs 前臺:vue2 式樣:uiKit 圖表:echarts 存儲:json文件 打包:webpack 功能:調查問卷的添加,修改,投票以及結果查看 ...
  • 在ios或android如果直接用webview在打開H5鏈接例如: 打開:http://localhost:8080/#/answer?id=1509335039582001 會變成 http://localhost:8080/ 造成根本打開不了想要的頁面(微信中獲取網頁授權的時候有#號也會有問題 ...
  • Js阻塞機制,跟Js引擎的單線程處理方式有關,每個window一個JS線程。所謂單線程,在某個特定的時刻只有特定的代碼能夠被執行,並阻塞其它的代碼。 由於瀏覽器是事件驅動的(Event driven),因此瀏覽器中很多行為是非同步(Asynchronized)的,很容易有事件被同時或者連續觸發。當非同步 ...
  • accept表示打開的系統文件目錄;capture表示的是系統所捕獲的預設設備,camera:照相機;camcorder:攝像機;microphone:照相+攝像。 如果不加上capture,則只會顯示相應的,例如上述三種依次是:拍照或圖庫,錄像或圖庫,錄像或拍照或圖庫,加上capture之後不會調 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...