Skip to content

Commit

Permalink
发布 0.2.0 版
Browse files Browse the repository at this point in the history
  • Loading branch information
lmk123 committed Jun 30, 2016
1 parent f5ba0fa commit 24af055
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 41 deletions.
48 changes: 29 additions & 19 deletions README.md
Expand Up @@ -17,7 +17,7 @@
读取与存储的都是 JSON 数据, 这意味着你能保留数据类型:

```js
const ls = new NamedStorage('local')
const ls = new NamedStorage()
ls.set('key', 1)
typeof ls.get('key') // "number"
```
Expand All @@ -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
Expand All @@ -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')
Expand All @@ -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'))
Expand All @@ -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`**启用此功能需要启用缓存**。详情见["懒保存"](#懒保存)
Expand All @@ -130,6 +136,10 @@ ls.namespace // 'hello:' -> 后面多了一个冒号

不要去更改这些属性的值, 你应该把这些属性都视为只读的。

### this.type (String)

`'local'``'session'`, 取决于你传入的 `options.session` 参数。

### this.storage

当前实例指向的存储空间, `localStorage``sessionStorage`
Expand All @@ -140,9 +150,9 @@ ls.namespace // 'hello:' -> 后面多了一个冒号

### this.caches (Object)

缓存的数据。如果没有启用缓存功能, 则此对象是一个 `undefined`
缓存的数据。如果没有启用缓存功能, 则此属性的值是 `undefined`

### this.name (String)
### this.namespace (String)

当前实例的命名空间。

Expand All @@ -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
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "namedstorage",
"version": "0.1.1",
"version": "0.2.0",
"description": "更高效的使用 localStorage 与 sessionStorage。",
"main": "storage.js",
"files": [
Expand Down
12 changes: 8 additions & 4 deletions storage.js
Expand Up @@ -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) {
Expand All @@ -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 会获取到同一个实例
Expand Down
35 changes: 18 additions & 17 deletions test/unit/all-test-spec.js
Expand Up @@ -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 () {
Expand All @@ -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')
Expand Down Expand Up @@ -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')
Expand All @@ -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)
Expand All @@ -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')

Expand All @@ -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')

Expand All @@ -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()

Expand All @@ -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')
Expand All @@ -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')
Expand Down

0 comments on commit 24af055

Please sign in to comment.