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 */) {          /* 初始化数据          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);

本文原创地址:https://www.linuxprobe.com/js-object.html编辑:王毅,审核员:暂无

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。
超哥软件库 » JavaScript面向对象轻松入门之综合