Home > Article > System Tutorial > Comprehensive introduction to object-oriented JavaScript
Almost all web applications need to save some data locally, so let's make a data storage.
When there is data stored locally, the local data is used, and when there is no data, the default data is used
Determine whether the local data is out of date. If it is out of date, do not use
By default, localStorage is used, but other storage methods are supported, and multi-party storage and multi-party reading are supported
According to the keywords in the requirements, we abstract three objects: data access, data, storage
The data storage manager is responsible for managing data and exposing the interface
Data objects are responsible for operating data
The storage is responsible for retaining data and reading data
DataStorageManagerBase exposes two interfaces save() and load(), simulates abstract classes, and tells subclasses to implement these two methods.
The following example implements a subclass using LocalStorage. Of course, you can also implement it using cookies or other methods.
Why should LocalStorage be re-encapsulated? Can't you just use it directly?
Because the APIs of various memories are different, after secondary encapsulation, we can ensure that no matter what memory is exposed to the outside world, the interfaces are save() and 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; } }
Operations on data: saving, reading, determining version, etc.
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>Data Access Object</strong></div> <p>For data object management, three interfaces getData(), setData(), and config() are exposed to the outside. Users use this module through these three interfaces</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);
The above is the detailed content of Comprehensive introduction to object-oriented JavaScript. For more information, please follow other related articles on the PHP Chinese website!