赞
踩
使用typescript进行了二次封装,"typescript": "5.2.2"。下有编译好的js代码。
目录
同源下多个应用进行存储隔离
- "use strict";
-
- // @ts-check
-
- /**
- * @description: 装饰器:检查函数入参类型
- * @param {string | string[]} type 基本数据类型 || 基本数据类型集合
- */
- function checkType(type: string | string[]) {
- return function (value: Function, { kind, name }) {
- return function (...args: any[]) {
- if (Array.isArray(type)) {
- args.forEach((item, index) => {
- if (typeof item !== type[index]) {
- throw new Error(`${kind}: ${name} params[${index}] is not ${type[index]}`);
- }
- })
- } else {
- args.forEach((item, index) => {
- if (typeof item !== type) {
- throw new Error(`${kind}: ${name} params[${index}] is not ${type}`);
- }
- })
- }
- return value.call(this, ...args);
- };
- }
- }
- /**
- * @description: 装饰器:限制参数长度
- * @param {number} extent 必传参数长度
- */
- function limit(extent: number) {
- return function (value: Function, { kind, name }) {
- return function (...args: any[]) {
- if (args.length < extent) {
- throw new Error(`${kind}: ${name} Expect ${extent} parameters, actual ${args.length}`);
- }
- return value.call(this, ...args);
- };
- }
- }
-
- abstract class Base {
- public original: Storage;
- protected prefix: string;
- constructor(original: Storage, prefix: string) {
- this.original = original;
- this.prefix = prefix;
- }
- protected getKey(key: string): string {
- return `${this.prefix}_${key}`;
- }
- }
-
- class WebStorage extends Base {
- constructor(original: Storage, prefix: string) {
- super(original, prefix);
- }
- @limit(1)
- @checkType("string")
- public getItem(key: string): string | null {
- const data = this.original.getItem(this.getKey(key));
- if (data === null) return null;
- try {
- const { value, indate } = JSON.parse(data);
- if (indate === null) return value;
- if (indate >= Date.now()) {
- return value;
- } else {
- this.removeItem(key);
- return null;
- }
- } catch (error) {
- return data;
- }
- }
- /**
- * @description: 调用存储
- * @param {string} key 键
- * @param {string} value 值
- * @param {timestamp} indate 时间戳-键值有效时间
- */
- @limit(2)
- @checkType(["string", "string", "number"])
- public setItem(key: string, value: string, indate?: number): void {
- this.original.setItem(
- this.getKey(key),
- JSON.stringify({
- value: value,
- indate: indate ? Date.now() + indate : null
- })
- );
- }
- @limit(1)
- @checkType("string")
- public removeItem(key: string): void {
- this.original.removeItem(this.getKey(key));
- }
- public clear(): void {
- this.original.clear();
- }
- }
-
- export default WebStorage;
代码不过多解释,不复杂,还有注释。
使用了新版ts装饰器,这也是我第一次尝试,据说性能更棒。
- "use strict";
- var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- if (typeof b !== "function" && b !== null)
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
- })();
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
- var useValue = arguments.length > 2;
- for (var i = 0; i < initializers.length; i++) {
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
- }
- return useValue ? value : void 0;
- };
- var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
- var _, done = false;
- for (var i = decorators.length - 1; i >= 0; i--) {
- var context = {};
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
- if (kind === "accessor") {
- if (result === void 0) continue;
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
- if (_ = accept(result.get)) descriptor.get = _;
- if (_ = accept(result.set)) descriptor.set = _;
- if (_ = accept(result.init)) initializers.unshift(_);
- }
- else if (_ = accept(result)) {
- if (kind === "field") initializers.unshift(_);
- else descriptor[key] = _;
- }
- }
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
- done = true;
- };
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
- if (ar || !(i in from)) {
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
- ar[i] = from[i];
- }
- }
- return to.concat(ar || Array.prototype.slice.call(from));
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- // @ts-check
- /**
- * @description: 装饰器:检查函数入参类型
- * @param {string | string[]} type 基本数据类型 || 基本数据类型集合
- */
- function checkType(type) {
- return function (value, _a) {
- var kind = _a.kind, name = _a.name;
- return function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- if (Array.isArray(type)) {
- args.forEach(function (item, index) {
- if (typeof item !== type[index]) {
- throw new Error("".concat(kind, ": ").concat(name, " params[").concat(index, "] is not ").concat(type[index]));
- }
- });
- }
- else {
- args.forEach(function (item, index) {
- if (typeof item !== type) {
- throw new Error("".concat(kind, ": ").concat(name, " params[").concat(index, "] is not ").concat(type));
- }
- });
- }
- return value.call.apply(value, __spreadArray([this], args, false));
- };
- };
- }
- /**
- * @description: 装饰器:限制参数长度
- * @param {number} extent 必传参数长度
- */
- function limit(extent) {
- return function (value, _a) {
- var kind = _a.kind, name = _a.name;
- return function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- if (args.length < extent) {
- throw new Error("".concat(kind, ": ").concat(name, " Expect ").concat(extent, " parameters, actual ").concat(args.length));
- }
- return value.call.apply(value, __spreadArray([this], args, false));
- };
- };
- }
- var Base = /** @class */ (function () {
- function Base(original, prefix) {
- this.original = original;
- this.prefix = prefix;
- }
- Base.prototype.getKey = function (key) {
- return "".concat(this.prefix, "_").concat(key);
- };
- return Base;
- }());
- var WebStorage = function () {
- var _a;
- var _classSuper = Base;
- var _instanceExtraInitializers = [];
- var _getItem_decorators;
- var _setItem_decorators;
- var _removeItem_decorators;
- return _a = /** @class */ (function (_super) {
- __extends(WebStorage, _super);
- function WebStorage(original, prefix) {
- var _this = _super.call(this, original, prefix) || this;
- __runInitializers(_this, _instanceExtraInitializers);
- return _this;
- }
- WebStorage.prototype.getItem = function (key) {
- var data = this.original.getItem(this.getKey(key));
- if (data === null)
- return null;
- try {
- var _b = JSON.parse(data), value = _b.value, indate = _b.indate;
- if (indate === null)
- return value;
- if (indate >= Date.now()) {
- return value;
- }
- else {
- this.removeItem(key);
- return null;
- }
- }
- catch (error) {
- return data;
- }
- };
- /**
- * @description: 调用存储
- * @param {string} key 键
- * @param {string} value 值
- * @param {timestamp} indate 时间戳-键值有效时间
- */
- WebStorage.prototype.setItem = function (key, value, indate) {
- this.original.setItem(this.getKey(key), JSON.stringify({
- value: value,
- indate: indate ? Date.now() + indate : null
- }));
- };
- WebStorage.prototype.removeItem = function (key) {
- this.original.removeItem(this.getKey(key));
- };
- WebStorage.prototype.clear = function () {
- this.original.clear();
- };
- return WebStorage;
- }(_classSuper)),
- (function () {
- var _b;
- var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_b = _classSuper[Symbol.metadata]) !== null && _b !== void 0 ? _b : null) : void 0;
- _getItem_decorators = [limit(1), checkType("string")];
- _setItem_decorators = [limit(2), checkType(["string", "string", "number"])];
- _removeItem_decorators = [limit(1), checkType("string")];
- __esDecorate(_a, null, _getItem_decorators, { kind: "method", name: "getItem", static: false, private: false, access: { has: function (obj) { return "getItem" in obj; }, get: function (obj) { return obj.getItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
- __esDecorate(_a, null, _setItem_decorators, { kind: "method", name: "setItem", static: false, private: false, access: { has: function (obj) { return "setItem" in obj; }, get: function (obj) { return obj.setItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
- __esDecorate(_a, null, _removeItem_decorators, { kind: "method", name: "removeItem", static: false, private: false, access: { has: function (obj) { return "removeItem" in obj; }, get: function (obj) { return obj.removeItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
- if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
- })(),
- _a;
- }();
- exports.default = WebStorage;
- import WebStorage from "./webStorage.js";
-
- const prefix = "projectName";
-
- const customStorage = {
- localStorage: new WebStorage(window.localStorage, prefix),
- sessionStorage: new WebStorage(window.sessionStorage, prefix)
- };
-
- customStorage.localStorage.setItem("test1", "a");
- console.log(customStorage.localStorage.getItem("test1"));
-
- customStorage.localStorage.setItem("test2", "b", 3000);
- console.log(customStorage.localStorage.getItem("test2"));
- setTimeout(() => {
- console.log(customStorage.localStorage.getItem("test2"))
- }, 5000);
基本对标原生态的使用方式,传参类型更严格,新增了存储过期的能力,使用无过多心智开销。 项目支持ts就用ts,仅支持js就用编译好的js,一样滴。使用方式建议挂载在一个公共的对象上,进行向下分发,不进行多次初始化。
觉得写的有问题的地方可以自己修改ts代码,重新使用typescript编译成js,欢迎大佬们评论区指点错误。如果有更好应对该场景的解决方案,留下链接让我学习一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。