# 封装sessionStorage

# 目的

  1. 简化并统一使用操作
  2. 增加功能(装饰器)
  3. 增加 值 类型标记
    1. 存取数据自动转化类
const Utils = function () { }

// toString 方法
Utils.prototype._toString = Object.prototype.toString
Utils.prototype.class2type = {
  '[object Boolean]': 'boolean',
  '[object Number]': 'number',
  '[object String]': 'string',
  '[object Function]': 'function',
  '[object Array]': 'array',
  '[object Date]': 'date',
  '[object RegExp]': 'regExp',
  '[object Object]': 'object',
}

// 类型检测, 返回对象类型字符串
Utils.prototype.type = function (obj) {
  const type = this._toString.call(obj)
  return obj === null ? String(obj) : this.class2type[type] || 'object'
}

// 实例化 Utils
const myUtil = new Utils()

function SessionStorage() { }

// 定义数据类型标识, 存储值前缀
SessionStorage.Types = {
  stringType: '00',
  numberType: '01',
  booleanType: '02',
  jsonType: '03',
  undefinedType: '04',
}

// 系统配置
// _$sys_session_readOnly: ['_$sys_session_01', '_$sys_session_02']
SessionStorage.SystemReadOnly = '_$sys_session_readOnly'

// 判断是否是系统key
SessionStorage.prototype.isSystemKey = function (key) {
  return key && key.indexOf('_$sys_session_') === 0
}

// 设置值
SessionStorage.prototype.put = function put(key, value, readOnly) {
  // 1、获取 key 类型
  const keyType = myUtil.type(key)
  if (keyType !== 'string') {
    console.error('the type of key is not string')
    return
  }

  // 2、判断 key 是否和系统保留值冲突
  if (this.isSystemKey(key)) {
    console.error('the key name is illegal');
    return
  }

  // 3、获取只读 key 配置
  let readOnlyKeys = window.sessionStorage.getItem(SessionStorage.SystemReadOnly)
  if (!readOnlyKeys) {
    readOnlyKeys = []
  } else {
    readOnlyKeys = JSON.parse(readOnlyKeys)
  }

  // 4、判断 key 是否为只读
  if (readOnlyKeys.indexOf(key) !== -1) {
    console.error('the key is read only');
    return
  }

  // 5、定义参数
  let param
  // 获取 value 类型
  const valueType = myUtil.type(value)
  switch (valueType) {
    case 'object':
      const s = JSON.stringify(value)
      param = SessionStorage.Types.jsonType + s
      break;
    case 'string':
      param = SessionStorage.Types.stringType + value
      break;
    case 'number':
      param = SessionStorage.Types.numberType + value
      break;
    case 'boolean':
      param = SessionStorage.Types.booleanType + value
      break;
    default:
      console.error('the type of value is not supported');
      break;
  }
  if (!param) {
    return
  }

  // 保存只读 key 集合
  if (readOnly && readOnly === true) {
    readOnlyKeys.push(key)
    readOnlyKeys = JSON.stringify(readOnlyKeys)
    window.sessionStorage.setItem(SessionStorage.SystemReadOnly, readOnlyKeys)
  }

  // 设置值
  window.sessionStorage.setItem(key, param)
}


// 获取值
SessionStorage.prototype.get = function get(key) {
  // 获取 key 类型
  const keyType = typeof key
  if (keyType !== 'string') {
    console.error('the type of key is not string');
    return undefined
  }

  // 获取 value
  const param = window.sessionStorage.getItem(key)
  if (param === null || param === undefined) {
    return param
  }

  // 获取 value 类型
  const valueType = param.substring(0, 2)
  // 获取 value
  let value = param.substring(2, param.length)
  switch (valueType) {
    case SessionStorage.Types.jsonType:
      value = JSON.parse(value)
      break;
    case SessionStorage.Types.numberType:
      value = Number(value)
      break;
    case SessionStorage.Types.booleanType:
      value = Boolean(value)
      break;
    default:
      break;
  }
  return value
}

// 移除项
SessionStorage.prototype.remove = function remove(key) {
  // 获取 key 类型
  const keyType = typeof key
  if (keyType !== 'string') {
    console.error('the type of key is not string');
    return undefined
  }

  // 判断 key 值是否和系统保留值冲突
  if (this.isSystemKey(key)) {
    console.error('the key name is illegal');
    return
  }

  // 获取只读 key 配置
  let readOnlyKeys = window.sessionStorage.getItem(SessionStorage.SystemReadOnly)
  if (!readOnlyKeys) {
    readOnlyKeys = []
  } else {
    readOnlyKeys = JSON.parse(readOnlyKeys)
  }

  // 判断 key 是否为只读
  if (readOnlyKeys.indexOf(key) !== -1) {
    console.error('the key is read only');
    return
  }

  window.sessionStorage.removeItem(key)
}

// 清空所有项
SessionStorage.prototype.clear = function clear() {
  // 获取只读 key 配置
  let readOnlyKeys = window.sessionStorage.getItem(SessionStorage.SystemReadOnly)
  if (!readOnlyKeys) {
    readOnlyKeys = []
  } else {
    readOnlyKeys = JSON.parse(readOnlyKeys)
  }

  // 临时缓存
  const tmpCache = {}
  // 保留 read only key
  for (let i = 0; i < readOnlyKeys.length; i++) {
    const key = readOnlyKeys[i];
    const value = window.sessionStorage.getItem(key)
    tmpCache[key] = value
  }

  // 清空
  window.sessionStorage.clear()

  if (readOnlyKeys) {
    // 还原 read only key
    for (let i = 0; i < readOnlyKeys.length; i++) {
      const key = readOnlyKeys[i];
      const value = tmpCache[key]
      window.sessionStorage.setItem(key, value)
    }

    // 保存 readOnlyKeys
    readOnlyKeys = JSON.stringify(readOnlyKeys)
    window.sessionStorage.setItem(SessionStorage.SystemReadOnly, readOnlyKeys)
  }
}

// 定义 session storage
const sessionStorage = new SessionStorage()
export default sessionStorage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218