LocalStorage API的二级封装和使用

64 min read
// --- LocalStorage util class --- //
function hoistLS(settings = {}) {
    const {
        verbose, // debug "messages" in the document.title
    } = settings;

    class LS {
        constructor(name) {
            this.name = name;
        }
        getItem(defaultValue) {
            return LS.getItem(this.name, defaultValue);
        }
        setItem(value) {
            LS.setItem(this.name, value);
        }
        removeItem() {
            LS.removeItem(this.name);
        }
        async pushItem(value) {  // array method
            await LS.pushItem(this.name, value);
        }
        async popItem(value) {   // array method
            await LS.popItem(this.name, value);
        }
        hasItem(value) {         // array method
            return LS.hasItem(this.name, value);
        }

        static getItem(name, defaultValue) {
            const value = localStorage.getItem(name);
            if (value === undefined) {
                return undefined;
            }
            if (value === null) { // when there is no such item
                LS.setItem(name, defaultValue);
                return defaultValue;
            }
            return JSON.parse(value);
        }
        static setItem(name, value) {
            localStorage.setItem(name, JSON.stringify(value));
        }
        static removeItem(name) {
            localStorage.removeItem(name);
        }
        static async pushItem(name, value) {
            const array = LS.getItem(name, []);
            array.push(value);
            LS.setItem(name, array);

            //sanity check
            await sleep(50);
            if (!LS.hasItem(name, value)) {
                if (verbose) {
                    document.title = "X" + document.title;
                }
                await LS.pushItem(name, value);
            }
        }
        static async popItem(name, value) { // remove from an array
            const array = LS.getItem(name, []);
            if (array.indexOf(value) !== -1) {
                array.splice(array.indexOf(value), 1);
                LS.setItem(name, array);

                //sanity check
                await sleep(50);
                if (LS.hasItem(name, value)) {
                    if (verbose) {
                        document.title = "Y" + document.title;
                    }
                    await LS.popItem(name, value);
                }
            }
        }
        static hasItem(name, value) { // has in array
            const array = LS.getItem(name, []);
            return array.indexOf(value) !== -1;
        }
    }

    return LS;
}

"hoistLS"的函数带有一个参数"settings",默认为空对象。函数内部定义了一个名为"LS"的类,它具有以下方法:

  1. constructor(name):构造函数,用于创建一个LS实例,并将name作为实例的属性。
  2. getItem(defaultValue):获取localStorage中name对应的值。如果值为undefined,则返回undefined。如果值为null,则设置name对应的值为defaultValue,并返回defaultValue。否则,将值解析为JavaScript对象后返回。
  3. setItem(value):将value保存到localStorage中name对应的项中,以JSON字符串格式存储。
  4. removeItem():从localStorage中删除name对应的项。
  5. async pushItem(value):将value压入(push)到localStorage中name对应的数组中。如果压入后的数组不包含value,则在50毫秒后进行"sanity check"(完整性检查),如果value仍然不在数组中,则在document.title中显示一个红色的方块,如果verbose属性为true,则会在debug模式下输出信息,然后再次调用pushItem方法。
  6. async popItem(value):从localStorage中name对应的数组中删除value。如果删除后的数组仍然包含value,则在50毫秒后进行"sanity check",如果value仍然在数组中,则在document.title中显示一个黄色的方块,如果verbose属性为true,则会在debug模式下输出信息,然后再次调用popItem方法。
  7. hasItem(value):在localStorage中name对应的数组中判断是否包含value,如果包含返回true,否则返回false。

同时,类LS还定义了以下静态方法:

  1. getItem(name, defaultValue):静态方法,获取localStorage中name对应的值。如果值为undefined,则返回undefined。如果值为null,则设置name对应的值为defaultValue,并返回defaultValue。否则,将值解析为JavaScript对象后返回。
  2. setItem(name, value):静态方法,将value保存到localStorage中name对应的项中,以JSON字符串格式存储。
  3. removeItem(name):静态方法,从localStorage中删除name对应的项。
  4. async pushItem(name, value):静态方法,将value压入(push)到localStorage中name对应的数组中。如果压入后的数组不包含value,则在50毫秒后进行"sanity check",如果value仍然不在数组中,则在document.title中显示一个红色的方块,如果verbose属性为true,则会在debug模式下输出信息,然后再次调用pushItem方法。
  5. async popItem(name, value):静态方法,从localStorage中name对应的数组中删除value。如果删除后的数组仍然包含value,则在50毫秒后进行"sanity check",如果value仍然在数组中,则在document.title中显示一个黄色的方块,如果verbose属性为true,则会在debug模式下输出信息,然后再次调用popItem方法。
  6. hasItem(name, value):静态方法,在localStorage中name对应的数组中判断是否包含value,如果包含返回true,否则返回false。

最后,函数返回LS类。