From 24af055c9b3f4e7f4e804ac602d2b84e0f1d170f Mon Sep 17 00:00:00 2001 From: lmk123 Date: Thu, 30 Jun 2016 14:34:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=200.2.0=20=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 48 +++++++++++++++++++++++--------------- package.json | 2 +- storage.js | 12 ++++++---- test/unit/all-test-spec.js | 35 +++++++++++++-------------- 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 1c44bb7..63e100f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ 读取与存储的都是 JSON 数据, 这意味着你能保留数据类型: ```js -const ls = new NamedStorage('local') +const ls = new NamedStorage() ls.set('key', 1) typeof ls.get('key') // "number" ``` @@ -27,8 +27,8 @@ typeof ls.get('key') // "number" 初始化 NamedStorage 实例时, 你可以提供一个命名空间(**NamedStorage 默认提供了一个命名空间——`"d"`, 即 default 的首字母**), 则对此实例的所有增删改查操作都会以这个命名空间作为前缀, 这能有效的避免冲突: ```js -const foo = new NamedStorage('local', { name: 'foo' }) -const bar = new NamedStorage('local', { name: 'bar' }) +const foo = new NamedStorage('foo') +const bar = new NamedStorage('bar') foo.set('bar', 1) bar.set('bar', 2) localStorage.getItem('bar') // null @@ -40,18 +40,18 @@ localStorage.getItem('bar:bar') // "2" 相同的存储空间与命名空间会得到同一个实例: ```js -const ss1 = new NamedStorage('session', { name: 'foo', cache: false }) -const ss2 = new NamedStorage('session', { name: 'foo', cache: true }) // 因为是同一个实例, 所以重新定义 `cache` 与 `lazySave` 配置不会生效 +const ss1 = new NamedStorage({ name: 'foo', session: true, cache: false }) +const ss2 = new NamedStorage({ name: 'foo', session: true, cache: true }) // 因为是同一个实例, 所以重新定义 `cache` 与 `lazySave` 配置不会生效 ss1 === ss2 // true -const ls = new NamedStorage('local', { name: 'foo' }) +const ls = new NamedStorage('foo') ls === ss1 // false ``` 因为有了命名空间的支持, 所以清空此实例的数据时可以选择只清空此命名空间内的数据, 而不是清空整个 WebStorage。 ```js -const ls = new NamedStorage('local', { name: 'foo' }) +const ls = new NamedStorage('foo') ls.set('bar', 1) localStorage.getItem('foo:bar') // '1' localStorage.setItem('bar', '2') @@ -74,7 +74,7 @@ localStorage.getItem('bar') // null NamedStorage 提供一个"懒保存"的功能, 如果启用的话, 则每次设置值时不会直接保存到 WebStorage 中, 而是在 `window.onunload` 事件中统一保存: ```js -const ls = new NamedStorage('local', { lazySave: true }) +const ls = new NamedStorage({ lazySave: true }) ls.set('foo', 'bar') localStorage.getItem('d:foo') // null window.dispatchEvent(new Event('unload')) @@ -85,25 +85,31 @@ localStorage.getItem('d:foo') // "\"bar\"" ## API -### new NamedStorage(type[, options]) +### new NamedStorage(name) -### type (String) +### name (String) -"local" 或 "session", 分别对应 `localStorage` 和 `sessionStorage`。 +等同于 `new NamedStorage({ name: name })`。 -### options.cache (Boolean) +### new NamedStorage([options]) -默认值为 `true`。设为 `false` 可禁用缓存功能。详情见[缓存数据](#缓存数据)。 +### options.session (Boolean) + +默认情况下使用 `localStorage`。设置此项为 `true` 则使用 `sessionStorage`。 ### options.name (String) 此实例的命名空间, 默认为 `"d"`。详情见[命名空间](#命名空间)。 ```js -const ls = new NamedStorage('local', { name: 'hello' }) +const ls = new NamedStorage({ name: 'hello' }) ls.namespace // 'hello:' -> 后面多了一个冒号 ``` +### options.cache (Boolean) + +默认值为 `true`。设为 `false` 可禁用缓存功能。详情见[缓存数据](#缓存数据)。 + ### options.lazySave (Boolean) 默认值为 `false`。**启用此功能需要启用缓存**。详情见["懒保存"](#懒保存)。 @@ -130,6 +136,10 @@ ls.namespace // 'hello:' -> 后面多了一个冒号 不要去更改这些属性的值, 你应该把这些属性都视为只读的。 +### this.type (String) + +`'local'` 或 `'session'`, 取决于你传入的 `options.session` 参数。 + ### this.storage 当前实例指向的存储空间, `localStorage` 或 `sessionStorage`。 @@ -140,9 +150,9 @@ ls.namespace // 'hello:' -> 后面多了一个冒号 ### this.caches (Object) -缓存的数据。如果没有启用缓存功能, 则此对象是一个 `undefined`。 +缓存的数据。如果没有启用缓存功能, 则此属性的值是 `undefined`。 -### this.name (String) +### this.namespace (String) 当前实例的命名空间。 @@ -157,8 +167,8 @@ ls.namespace // 'hello:' -> 后面多了一个冒号 如果你不自定义 `name` 的话, 你每次得到的都是同一个实例: ```js -const s1 = new NamedStorage('local', { cache: false }) -const s2 = new NamedStorage('local', { cache: true }) +const s1 = new NamedStorage({ cache: false }) +const s2 = new NamedStorage({ cache: true }) s1 === s2 // true s2.namespace === 'd:' // true s2.useCache // false @@ -167,7 +177,7 @@ s2.useCache // false ### 如果你启用了缓存, 则直接更改 WebStorage 内的值不会反映到 NamedStorage ```js -const ls = new NamedStorage('local') +const ls = new NamedStorage() ls.set('foo', 'bar') localStorage.getItem('d:foo') // 'bar diff --git a/package.json b/package.json index a87db98..bd407e8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "namedstorage", - "version": "0.1.1", + "version": "0.2.0", "description": "更高效的使用 localStorage 与 sessionStorage。", "main": "storage.js", "files": [ diff --git a/storage.js b/storage.js index a21a790..ee77dd5 100644 --- a/storage.js +++ b/storage.js @@ -20,6 +20,9 @@ var isFunction = function (v) { return typeof v === 'function' } + var isString = function (v) { + return typeof v === 'string' + } var emptyObj = {} var hasOwn = emptyObj.hasOwnProperty var forIn = function (obj, handler) { @@ -46,16 +49,17 @@ /** * 构造函数 - * @param {String} type - "local" 或 "session"。数据应该在哪个 storage 内读取和设置 - * @param [options] + * @param {String|Object} [options] - 当这个参数是字符串时, 则等同于设置 name + * @param {Boolean} [options.session] - 默认使用 localStorage。设置此项为 true 则使用 sessionStorage * @param {String} [options.name="d"] - key 的前缀。添加此前缀能避免污染全局 storage 数据 * @param {Boolean} [options.cache=true] - 若启用缓存, 则读取数据时会先从缓存内读取,然后从 storage 内读取 * @param {Boolean} [options.lazySave=false] - 若启用, 则设置数据时不会立刻写入 storage, 而是在 window.onunload 事件时写入 * @constructor */ - function MyStorage (type, options) { - var _options = options || emptyObj + function MyStorage (options) { + var _options = isString(options) ? { name: options } : (options || emptyObj) var namespace = (_options.name || 'd') + ':' + var type = _options.session ? 'session' : 'local' var thisType = allStorages[type] // 相同的 type 与 namespace 会获取到同一个实例 diff --git a/test/unit/all-test-spec.js b/test/unit/all-test-spec.js index 6df7fa3..fe2c2a4 100644 --- a/test/unit/all-test-spec.js +++ b/test/unit/all-test-spec.js @@ -6,7 +6,7 @@ describe('NamedStorage', function () { var Event = window.Event function uuid () { - return Math.random() + Date.now() + return String(Math.random() + Date.now()) } afterEach(function () { @@ -15,28 +15,28 @@ describe('NamedStorage', function () { }) it('会提供默认配置', function () { - var l = new NamedStorage('local') + var l = new NamedStorage() expect(l.namespace).toBe('d:') expect(l.useCache).toBe(true) expect(l.saveOnUnload).toBeFalsy() }) it('相同的存储空间与命名空间会得到同一个实例', function () { - var ls1 = new NamedStorage('local', { name: 'x', cache: false }) - var ls2 = new NamedStorage('local', { name: 'x', cache: true }) - var ss1 = new NamedStorage('local', { name: 'y' }) + var ls1 = new NamedStorage({ name: 'x', cache: false }) + var ls2 = new NamedStorage({ name: 'x', cache: true }) + var ss1 = new NamedStorage('y') expect(ls2).toBe(ls1) expect(ss1).not.toBe(ls1) expect(ls2.useCache).toBe(false) }) it('lazySave 功能需要启用缓存', function () { - var l = new NamedStorage('local', { name: 'z', cache: false, lazySave: true }) + var l = new NamedStorage({ name: 'z', cache: false, lazySave: true }) expect(l.saveOnUnload).toBeFalsy() }) it('设置值时会保留数据类型', function () { - var l = new NamedStorage('session', { name: uuid() }) + var l = new NamedStorage({ name: uuid(), session: true }) l.set('number', 1) l.set('boolean', true) l.set('string', 'hi') @@ -76,7 +76,7 @@ describe('NamedStorage', function () { }) it('设置与读取的对象不是同一个', function () { - var l = new NamedStorage('local', { name: uuid() }) + var l = new NamedStorage(uuid()) var obj = {} l.set('obj', obj) var obj2 = l.get('obj') @@ -91,7 +91,7 @@ describe('NamedStorage', function () { }) it('设置的值为 null 或 undefined 时会删除数据', function () { - var l = new NamedStorage('local', { name: uuid() }) + var l = new NamedStorage(uuid()) l.set('x', 1) expect(localStorage.getItem(l.namespace + 'x')).toBe('1') l.set('x', null) @@ -106,14 +106,14 @@ describe('NamedStorage', function () { }) it('若启用缓存则读取值后会缓存这个值', function () { - var l = new NamedStorage('local', { name: uuid() }) + var l = new NamedStorage(uuid()) localStorage.setItem(l.namespace + 'x', 'not json') expect(l.get('x')).toBe('not json') expect(l.caches.x).toBe('not json') }) it('启用缓存时不会意识到 WebStorage 发生了变化', function () { - var l = new NamedStorage('local', { name: uuid() }) + var l = new NamedStorage(uuid()) l.set('x', 1) expect(localStorage.getItem(l.namespace + 'x')).toBe('1') @@ -122,7 +122,7 @@ describe('NamedStorage', function () { }) it('关闭缓存后, 每次都会从 WebStorage 内读取数据', function () { - var l = new NamedStorage('local', { name: uuid(), cache: false }) + var l = new NamedStorage({ name: uuid(), cache: false }) l.set('x', 1) expect(localStorage.getItem(l.namespace + 'x')).toBe('1') @@ -131,7 +131,7 @@ describe('NamedStorage', function () { }) it('启用 lazySave 后, 只会在 window.onunload 事件时才会将数据写入存储空间', function () { - var l = new NamedStorage('local', { name: uuid(), lazySave: true }) + var l = new NamedStorage({ name: uuid(), lazySave: true }) l.set('x', 1) expect(localStorage.getItem(l.namespace + 'x')).toBeNull() @@ -151,8 +151,9 @@ describe('NamedStorage', function () { }) it('清空时默认只会清空当前命名空间下的数据', function () { - var ls = new NamedStorage('local', { name: uuid() }) - var ls2 = new NamedStorage('local', { name: uuid() }) + var ls = new NamedStorage(uuid()) + var ls2 = new NamedStorage(uuid()) + ls.set('key', 'value') localStorage.setItem(ls.namespace + 'key2', 'value2') ls2.set('key3', 'value3') @@ -165,8 +166,8 @@ describe('NamedStorage', function () { }) it('清空时传入 true 会清空当前存储空间的所有数据', function () { - var ls = new NamedStorage('local', { name: uuid() }) - var ls2 = new NamedStorage('local', { name: uuid() }) + var ls = new NamedStorage(uuid()) + var ls2 = new NamedStorage(uuid()) ls.set('key', 'value') localStorage.setItem('abc', 'value2') ls2.set('key3', 'value3')