迹忆客 专注技术分享

当前位置:主页 > 学无止境 > WEB前端 > JavaScript >

我如何检测和使用 localStorage:一个简单的 JavaScript 模式

作者:迹忆客 最近更新:2023/01/10 浏览次数:

传统的方法

以下是检测 localStorage 支持的方法:

// Feature test
var hasStorage = (function() {
    try {
        localStorage.setItem(mod, mod);
        localStorage.removeItem(mod);
        return true;
    } catch (exception) {
        return false;
    }
}());

请注意 ,访问全局 localStorage 对象可能会引发异常,因此需要在该测试的 try-catch 块内完成。

Modernizr 就是这样做的(并在源代码中广泛记录了该技术)。 它可以根据我们希望支持的浏览器和边缘情况进行一些简化,但目前这是最强大的功能检测。

通过上面的代码片段,我们可以在代码中使用 localStorage,如下所示

if (hasStorage) {
    // Use `localStorage` here, e.g.
    localStorage.setItem('foo', 'bar');
    localStorage.lol = 'wat';
    localStorage.removeItem('foo');
}

当然,这并不是什么新鲜事。 那我为什么要写这个? 好吧,我一直在使用一种略有不同的技术,它有一些优点,我想分享一下。

新模式

让我们看看如果我们稍微调整一下上面的脚本会发生什么:

// Feature detect + local reference
var storage = (function() {
    var uid = new Date;
    var result;
    try {
        localStorage.setItem(uid, uid);
        result = localStorage.getItem(uid) == uid;
        localStorage.removeItem(uid);
        return result && localStorage;
    } catch (exception) {}
}());

与之前的代码片段相比,变化不大。 有以下三个区别:

  • 此代码段实际上检测 localStorage 是否正常工作,方法是检查 getItem() 返回的值是否与使用 setItem() 设置的值相同。
  • 如果 localStorage 特征检测成功,则其结果为真。 所以我们追加 && localStorage,如果测试成功,这会导致存储变量成为对全局 localStorage 对象的引用。 换句话说,如果不支持 localStoragestorage === undefined,这是错误的。 如果支持,storage === window.localStorage,这是真的。
  • 我们没有从 catch 块中返回 false,而是什么都不返回。 如果捕获到错误,存储将是未定义的,这是错误的。

我们可以更进一步,避免对 localStorage(如果可用)的重复范围查找,如下所示:

// Feature detect + local reference
var storage = (function() {
    var uid = new Date;
    var storage;
    var result;
    try {
        (storage = window.localStorage).setItem(uid, uid);
        result = storage.getItem(uid) == uid;
        storage.removeItem(uid);
        return result && storage;
    } catch (exception) {}
}());

正如 Juriy “kangax” Zaytsev 指出的那样,完全避免使用匿名函数是可能的:

// Feature detect + local reference
var storage;
var fail;
var uid;
try {
    uid = new Date;
    (storage = window.localStorage).setItem(uid, uid);
    fail = storage.getItem(uid) != uid;
    storage.removeItem(uid);
    fail && (storage = false);
} catch (exception) {}

它工作得很好,而且由于减少了函数调用的数量,甚至比前面的代码片段更有效。

无论如何,我们可以像这样使用这些片段中的任何一个:

if (storage) {
    // Use `storage` here, e.g.
    storage.setItem('foo', 'bar');
    storage.lol = 'wat';
    storage.removeItem('foo');
}

再简单不过了!

有用吗?

我最喜欢这种模式是因为它的优雅,但是——假设你的代码在它自己的范围内以防止将变量泄漏到全局范围——还有一些(次要的)性能优势:

  • 只有一个变量(storage)——它既可以用来检查是否支持 localStorage 也可以用来操作它。
  • 通过直接使用局部存储变量而不是全局 localStorage 对象,范围查找保持在最低限度。
  • 始终使用引用 localStorage 的局部变量会导致压缩/缩小后的文件大小更小。
  • 这是一个边缘案例,但如果我们需要将整个 Web 应用程序从 localStorage 切换到 sessionStorage,我们甚至不必更改变量名称。 只需将出现的 localStorage 替换为 sessionStorage 即可。 (这些 API 是相同的,甚至特征检测也可以用相同的方式完成。)

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

JavaScript POST

发布时间:2024/03/23 浏览次数:96 分类:JavaScript

本教程讲解如何在不使用 JavaScript 表单的情况下发送 POST 数据。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便