需求:
几乎所有的web应用都需要保存数据一些到本地,那么我们就来做一个数据储存器吧。
详细需求:
当本地储存有数据时,取用本地的数据,没有时使用默认的数据
判断本地的数据是否过时,如果过时则不使用
默认使用localStorage,但支持使用其它储存方式,并且要支持多方储存,多方读取
抽象出对象
根据需求里面的关键字,我们抽象出三个对象:数据访问、数据、储存器
数据储存管理器负责管理数据,对外暴露接口
数据对象负责对数据的操作
储存器负责保持数据,读取数据
储存器对象
DataStorageManagerBase暴露两个接口save()和load(),模拟抽象类,告诉子类一定要实现这两个方法。
下面的例子用LocalStorage实现了一个子类,当然你也可以用cookie或其它方式实现。
为什么要把LocalStorage这些储存器进行二次封装呢?直接用不就可以了吗?
因为各种储存器等api都是不一样等,我们二次封装后可以确保无论什么储存器对外暴露的接口都是save()和load()。
/*模拟数据储存器抽象类,其实这个类不要也可以*/ class DataStorageManagerBase { static getIns() { /* 储存器在整个应用的生命周期里应该只有一个xwenw.com/tag/%e5%ae%9e%e4%be%8b" target="_blank">实例 */ 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 <div style="font-size: 14pt; color: white; background-color: black; border-left: red 10px solid; padding-left: 14px; margin-bottom: 20px; margin-top: 20px;"><strong>数据访问对象</strong></div> <p>对数据对象管理,对外暴露三个接口getData(),setData(),config(),用户通过这三个接口使用这个模块</p> <pre class="brush:php;toolbar:false">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);
登录后复制
以上就是JavaScript面向对象轻松入门之综合的详细内容,更多请关注小闻网其它相关文章!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)