阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

JavaScript面向对象轻松入门之综合

300次阅读
没有评论

共计 3887 个字符,预计需要花费 10 分钟才能阅读完成。

需求:

几乎所有的 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 */) {
        /* 初始化数据
        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);

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计3887字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19355
评论数
4
阅读量
8258495
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛 NAS-7:手把手教你免费内网穿透 -Cloudflare tunnel 前言 大家好,我是星...
星哥带你玩飞牛NAS-2:飞牛配置RAID磁盘阵列

星哥带你玩飞牛NAS-2:飞牛配置RAID磁盘阵列

星哥带你玩飞牛 NAS-2:飞牛配置 RAID 磁盘阵列 前言 大家好,我是星哥之前星哥写了《星哥带你玩飞牛 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞定

多服务器管理神器 Nexterm 横空出世!NAS/Win/Linux 通吃,SSH/VNC/RDP 一站式搞...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
如何免费使用强大的Nano Banana Pro?附赠邪修的用法

如何免费使用强大的Nano Banana Pro?附赠邪修的用法

如何免费使用强大的 Nano Banana Pro?附赠邪修的用法 前言 大家好,我是星哥,今天来介绍谷歌的 ...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛NAS-1:安装飞牛NAS

星哥带你玩飞牛 NAS-1:安装飞牛 NAS 前言 在家庭和小型工作室场景中,NAS(Network Atta...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛 NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手! 作为动漫爱好者,你是否还在为...
免费获得大模型的Api-Key的方法:英伟达提供GLM-4.7、Minimax M2.1模型和GitHub的AI大模型API申请

免费获得大模型的Api-Key的方法:英伟达提供GLM-4.7、Minimax M2.1模型和GitHub的AI大模型API申请

  免费获得大模型的 Api-Key 的方法:英伟达提供 GLM-4.7、Minimax M2.1 ...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

  300 元就能买到的 ” 小钢炮 ”?惠普 7L 四盘位小主机解析 最近...