一个简单的本地存储操作,直接操作模型的方式操作缓存
来源:互联网 发布:域名解析隐藏端口号 编辑:程序博客网 时间:2024/06/03 15:12
一个简单的本地存储操作,直接操作模型的方式操作缓存
eg:
var m = store.config({model: {name: '韩没灭',age: 16,child: {name: '李磊',age: 1,books: [1,2,3,4]}},namespace: 'test'}); m.defineProperty('bbb', {}).defineProperty('b', {a:1}); console.log(m.getProperty('bbb.b.a')); console.log(m.bbb.b.a) m.forEach(function(value, key){console.log(value, key)}, true)
(function (factory) { if (typeof define === 'function' && define.amd) { define(factory) } else { window.store = factory() }})(function () { 'use strict' var utils = { isArray: function (obj) { return Object.prototype.toString.call(obj) === '[object Array]' }, isString: function (obj) { return Object.prototype.toString.call(obj) === '[object String]' }, isFunction: function (obj) { return Object.prototype.toString.call(obj) === '[object Function]' }, isUndefined: function (obj) { return Object.prototype.toString.call(obj) === '[object Undefined]' }, isObject: function (obj) { return Object.prototype.toString.call(obj) === '[object Object]' } } function Proxy(model) { if (model) { var data = clone(model), self = this Object.defineProperty(self, '$M', { get: function () { return model } }) Object.defineProperty(self, '$D', { get: function () { return data } }) if (utils.isArray(model)) { Object.defineProperty(this, 'length', { get: function () { return this.$M.length } }) new Array('forEach','map','filter','some','every','indexOf','lastIndexOf','reduce','reduceRight').forEach(function(method){ self[method] = function (callback) { this.$M[method] (function(){ callback.apply(self, Array.prototype.slice.call(arguments).slice()) }) } }) this.push = function (val) { var len = this.$M.length this.$M.push(val) this.$P.self.listen(this.$P.$K + '.' + len, val, null) } this.isEmpty = function () { return this.$M.length === 0 } this.set = function (i, val) { var self = this this.$M[i] = val this.$P.self.listen(this.$P.$K + '.' + i, val, null) } this.reverse = function () { return this.$M.slice(0).reverse() } this.reverseEach = function (callback) { this.$M.slice(0).reverse().forEach(callback) } this.get = function (i) { return i>= 0 ? this.$M[i] : self.$M[this.length + i] } return this } Object.keys(model).forEach(function (key) { if (utils.isObject(model[key]) || utils.isArray(model[key])) { data[key] = new Proxy(model[key]) Object.defineProperty(data[key], '$P', { get: function () { return {$K: key, $D: data, self: self} } }) } else if (utils.isFunction(model[key])) { data[key] = new Proxy(model[key]()) Object.defineProperty(data[key], '$P', { get: function () { return {$K: key, $D: data, self: self} } }) } Object.defineProperty(self, key, { get: function () { return data[key] }, set: function (value) { var oldVal = data[key], newVal = value; if(utils.isObject(newVal) || utils.isArray(newVal)) { data[key] = new Proxy(newVal) Object.defineProperty(data[key], '$P', { get: function () { return {$K: key, $D: self.$D, self: self} } }) } else { data[key] = newVal } self.listen(key, newVal, oldVal) model[key] = value } }) }) } return this } /** * * @param callback function(value, key) * @param recursion true | false */ Proxy.prototype.forEach = function (callback, recursion) { console.assert(callback, 'callback is must!') for(var prop in this.$D) { if(this.$D[prop].forEach && recursion) { this.$D[prop].forEach(callback) } else { callback.call(this, this.$M[prop], prop) } } } Proxy.prototype.size = function () { return this.$M.length || Object.keys(this.$M).length } /** * * @param propertyName a.b.c.d * @param proxy trye | false */ Proxy.prototype.getProperty = function (propertyName, proxy) { return getField(proxy ? this.$D : this.$M, propertyName) } Proxy.prototype.removeProperty = function (propertyName) { this[propertyName] = undefined } Proxy.prototype.defineProperty = function(propertyName, propertyVal) { var self = this if (utils.isObject(propertyVal) || utils.isArray(propertyVal)) { self.$D[propertyName] = new Proxy(propertyVal) Object.defineProperty(self.$D[propertyName], '$P', { get: function () { return {$K: propertyName, $D: self.$D, self: self} } }) } else if (utils.isFunction(propertyVal)) { self.$D[propertyName] = new Proxy(propertyVal()) Object.defineProperty(self.$D[propertyName], '$P', { get: function () { return {$K: propertyName, $D: self.$D, self: self} } }) } else { self.$D[propertyName] = propertyVal } if(!self[propertyName]) { Object.defineProperty(self, propertyName, { get: function () { return self.$D[propertyName] }, set: function (value) { if(utils.isObject(value) || utils.isArray(value)) { self.$D[propertyName] = new Proxy(value) Object.defineProperty(self.$D[propertyName], '$P', { get: function () { return {$K: propertyName, $D: self.$D, self: self} } }) } self.listen(propertyName, value, self.$D[propertyName]) self.$M[propertyName] = value } }) } self.listen(propertyName, propertyVal, self.$D[propertyName]) return self[propertyName] } var keys = function (proxy, prop) { var array = [].concat(prop), p = proxy.$P if (p) { array = array.concat(keys(p.self, p.$K)) } return array } Proxy.prototype.listen = function (prop, newVal, oldVal) { if (newVal instanceof Proxy) newVal = newVal.$M setField(model, keys(this, prop).reverse().join('.'), newVal) storage.setItem(namespace, JSON.stringify(model)) } var storage = localStorage, model, namespace, strict var setField = function (obj, key, val) { if (key === "") return obj obj = obj || {} var dot = key.indexOf('.') if (dot != -1) { var k = key.substring(0, dot) if (utils.isArray(obj)) { k = k.match(/\d+/)[0] } obj[k] = setField(obj[k], key.substring(dot + 1), val) } else { if (utils.isArray(obj)) { key = key.match(/\d+/)[0] } obj[key] = val } return obj } var getField = function (obj, key) { if (!obj || obj === null) return if (utils.isString(obj) && obj.indexOf('{') != -1) { obj = (0, eval)('(' + obj + ')') } if (utils.isUndefined(key) || key === '' || key === null) return obj var keys = [] if (key.indexOf('.') != -1) { keys = key.split('.') } else { keys.push(key) } var val if (utils.isObject(obj)) { for (var i = 0;i < keys.length;i++) { var ak = keys[i] if (utils.isArray(obj)) { ak = ak.match(/\d+/)[0] } obj = obj[ak] if (!obj) return } val = obj } return val } function parseKey(key) { var spiltIndex = key.indexOf(':') if (spiltIndex === -1) return key namespace = key.substring(0, spiltIndex) return key.substring(spiltIndex + 1) } function init() { if (storage.getItem(namespace) === null) { model = model || {} storage.setItem(namespace, JSON.stringify(model)) } else { model = JSON.parse(storage.getItem(namespace)) } } function clone(obj) { if (null === obj || 'object' !== typeof obj) return obj if (obj instanceof Date) { var copy = new Date() copy.setTime(obj.getTime()) return copy } if (obj instanceof Array) { var copy = [] for (var i = 0, len = obj.length;i < len;++i) { copy[i] = clone(obj[i]) } return copy } if (obj instanceof Object) { var copy = {} for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]) } return copy } throw new Error('Unable to copy obj! Its type isn\'t supported.') } return { setStorage: function (store) { storage = store || localStorage }, /** * @param options {namespace:'', model:'', strict: false, storage: localStorage} */ config: function (options) { options = options || {} namespace = options.namespace || 'DEFAULT_STORE_KEY' strict = options.strict || false //如果开启 则无法存储model中不存在的属性 this.setStorage(options.store || localStorage) model = clone(options.model) init.call(this) return new Proxy(model) }, refresh: function () { storage.setItem(namespace, JSON.stringify(model)) }, set: function (key, value) { key = parseKey(key) init.call(this) if (strict && !model[key]) { throw new Error('Can not insert under strict mode') } setField(model, key, value) this.refresh() }, get: function (key) { key = parseKey(key) init.call(this) return getField(model, key) }, remove: function (key) { init.call(this) delete model[key] this.refresh() }, each: function (callback) { init.call(this) if (!callback || typeof callback !== 'function') { throw new Error('callback must!') } for (var prop in this.model) { callback.call(this, model[prop], prop) } }, keys: function () { init.call(this) return Object.keys(model) }, pretty: function () { init.call(this) var pretty = JSON.stringify(model, null, ' ') console.log(pretty) return pretty }, clear: function () { if(namespace) storage.removeItem(namespace) else storage.clear() } }})
0 0
- 一个简单的本地存储操作,直接操作模型的方式操作缓存
- 一个简单的操作
- 简单的IO操作示例(不带缓存方式)
- 一个简单的c#+sqlserver本地操作程序
- mysql 存储过程一个简单的循环遍历操作数据
- Elasticsearch的存储模型和读写操作
- elasticsearch的存储模型和读写操作
- 一个简单的异步操作
- Yii 登录表单模型的简单操作
- django中模型的简单操作
- 银行账户操作的简单模型
- javascript的本地操作
- Git的本地操作
- git的本地操作
- Smarty的缓存操作
- JDBC操作简单的存储过程
- 最简单的xml操作方式!
- 一种简单的c++文件操作方式
- C++Notes03_数据类型(Data Type)
- Thread.interrupt 快速解读
- cell的线不贴边
- URL中 中文转码
- 欢迎使用CSDN-markdown编辑器
- 一个简单的本地存储操作,直接操作模型的方式操作缓存
- PHP 对象的存储与传输(序列化 serialize 对象)
- HTTP 1.1与HTTP 1.0的比较
- 使用pm2部署nodejs
- 杨辉三角/二项式定理
- AES加密
- git--全局删除项目中的.DS_Store文件
- Map遍历的四种方法及比较
- 在UIAlterView的代理方法中 点击确定时 添加一个UIView到[[UIApplication sharedApplication].keyWindow上只出现了0.5秒左右就消失的问题