





























Disclaimer: This is not a localStorage tutorial — see Chapter 7 of Dive Into HTML5 if that’s what you’re looking for. Read on if you’re still interested.
Here’s how you can detect localStorage support:
// Feature test
var hasStorage = (function() {
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch (exception) {
return false;
}
}());
Note that accessing the global localStorage object may throw an exception, so it needs to be done inside a try-catch block for this test.
Modernizr does it this way (and documents the technique extensively in the source). It could be simplified a bit depending on the browsers and edge cases you wish to support, but for now this is the most robust feature detect out there.
With the above snippet, you can make use of localStorage in your code as follows:
if (hasStorage) {
// Use `localStorage` here, e.g.
localStorage.setItem('foo', 'bar');
localStorage.lol = 'wat';
localStorage.removeItem('foo');
}
Of course, this is nothing new. So why am I writing this? Well, I’ve been using a slightly different technique that has a few advantages, and I’d like to share it.
Let’s see what happens if we tweak the above script just a little bit:
// 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) {}
}());
Compared to the previous snippet, not much has changed. There are three differences:
localStorage works correctly, by checking if the value that is returned by getItem() is the same one that was set using setItem().localStorage feature detect is successful, its result will be truthy. So we append && localStorage, which causes the storage variable to become a reference to the global localStorage object if the test was successful. In other words, if localStorage isn’t supported, storage === undefined, which is falsy. If it is supported, storage === window.localStorage, which is truthy.returning false from the catch block, we return nothing at all. If an error is caught, storage will be undefined, which is falsy.We could take it one step further and avoid the repeated scope lookups for localStorage (if it’s available) as follows:
// 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) {}
}());
As Juriy “kangax” Zaytsev noted, it’s possible to avoid the anonymous function entirely:
// 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) {}
It works just as well, and is even more efficient than the previous snippet because of the reduced number of function calls.
Anyhow, you can use any of these snippets like this:
if (storage) {
// Use `storage` here, e.g.
storage.setItem('foo', 'bar');
storage.lol = 'wat';
storage.removeItem('foo');
}
It couldn’t be simpler!
I mostly like this pattern because of its elegance, but — assuming your code is inside its own scope to prevent leaking variables to the global scope — there are some (minor) performance benefits as well:
storage) — and it can be used both to check if localStorage is supported and to manipulate it.storage variable instead of the global localStorage object directly, scope lookups are kept to a minimum.localStorage results in a smaller file size after compression/minification.localStorage to sessionStorage for your entire web app, you won’t even have to change your variable names. Just replace the one occurence of localStorage with sessionStorage and you’re done. (These APIs are identical, and even the feature detect can be done the same way.)I’ve been using localStorage (and sessionStorage) in this example, but of course the exact same pattern could be applied in other cases as well. Can you think of other examples?
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。