**一、基本概念**
- **共同点**:
- 存储大小一般为 5MB 左右(不同浏览器可能有差异)。
- 仅在浏览器端存储,不参与服务器通信。
- 数据以键值对形式存储,且始终为字符串类型。
- **不同点**:
- **`localStorage`**:数据会永久存储,除非主动删除(清空浏览器缓存或调用 `localStorage.clear()`)。
- **`sessionStorage`**:数据仅在当前会话期间有效,关闭窗口或标签页后自动清除。
**二、使用方法**
**1. 存储数据**
javascript
// 方法一:使用 setItem()
localStorage.setItem('username', 'John');
sessionStorage.setItem('token', '123456');
// 方法二:直接赋值(不推荐,可能有兼容性问题)
localStorage.user = 'John';
sessionStorage.token = '123456';
**2. 获取数据**
javascript
// 方法一:使用 getItem()
const username = localStorage.getItem('username'); // 返回 "John"
const token = sessionStorage.getItem('token'); // 返回 "123456"
// 方法二:直接访问(不推荐,不存在的键会返回 undefined)
const user = localStorage.user;
**3. 删除数据**
javascript
// 删除指定键
localStorage.removeItem('username');
sessionStorage.removeItem('token');
// 清空所有存储
localStorage.clear();
sessionStorage.clear();
**4. 获取键名和存储长度**
javascript
// 获取存储的键数量
const localStorageLength = localStorage.length;
// 获取指定索引的键名
const firstKey = localStorage.key(0); // 获取第一个键
// 遍历所有键值对
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
console.log(`${key}: ${value}`);
}
**三、存储复杂数据类型**
由于 `localStorage` 和 `sessionStorage` 只能存储字符串,需要使用 `JSON.stringify()` 和 `JSON.parse()` 处理复杂数据类型:
javascript
// 存储对象
const user = { name: 'John', age: 30 };
localStorage.setItem('user', JSON.stringify(user));
// 获取并解析对象
const storedUser = JSON.parse(localStorage.getItem('user'));
console.log(storedUser.name); // 输出 "John"
// 存储数组
const fruits = ['apple', 'banana', 'cherry'];
sessionStorage.setItem('fruits', JSON.stringify(fruits));
// 获取并解析数组
const storedFruits = JSON.parse(sessionStorage.getItem('fruits'));
console.log(storedFruits[1]); // 输出 "banana"
**四、事件监听**
当 `localStorage` 或 `sessionStorage` 发生变化时(同一域名下的其他窗口或标签页),会触发 `storage` 事件:
javascript
// 在其他窗口/标签页监听 storage 事件
window.addEventListener('storage', function(event) {
console.log(`键 ${event.key} 发生变化`);
console.log(`旧值: ${event.oldValue}`);
console.log(`新值: ${event.newValue}`);
console.log(`变化发生在: ${event.url}`);
});
**注意**:`sessionStorage` 的变化不会触发 `storage` 事件,因为它只在当前会话有效。
**五、区别对比表**
| **特性** | **localStorage** | **sessionStorage** |
|------------------------|--------------------------------------|--------------------------------------|
| **数据有效期** | 永久存储,需手动清除 | 窗口/标签页关闭后自动清除 |
| **作用域** | 同一域名下所有窗口/标签页共享 | 仅当前窗口/标签页有效 |
| **数据共享** | 不同窗口/标签页可读写相同数据 | 不同窗口/标签页数据相互独立 |
| **storage 事件触发** | 数据变化时触发(同一域名其他窗口) | 不触发 |
| **典型应用场景** | 用户偏好设置、长期缓存 | 临时表单数据、会话状态 |
**六、使用注意事项**
1. **数据类型限制**:所有值都会被转换为字符串存储,存储对象或数组时需先序列化。
2. **性能问题**:频繁读写大量数据可能影响页面性能,建议控制存储大小。
3. **兼容性**:现代浏览器均支持,但 IE8 及以下版本不支持。
4. **安全风险**:不要存储敏感信息(如密码、信用卡号),因为存储的数据可被同一域名下的 JavaScript 访问。
**七、示例代码:简单的 Todo 列表**
javascript
// 添加任务到 localStorage
function addTask(task) {
// 获取现有任务
const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
tasks.push(task);
// 保存到 localStorage
localStorage.setItem('tasks', JSON.stringify(tasks));
}
// 显示所有任务
function displayTasks() {
const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
tasks.forEach(task => console.log(task));
}
// 使用示例
addTask('学习 JavaScript');
addTask('练习 Canvas');
displayTasks(); // 输出所有任务
**八、兼容性检测**
javascript
function checkStorageSupport() {
try {
const testKey = 'storage_test';
localStorage.setItem(testKey, 'test');
localStorage.removeItem(testKey);
return true;
} catch (e) {
return false;
}
}
if (checkStorageSupport()) {
// 支持 localStorage/sessionStorage
} else {
// 不支持,需使用其他存储方案(如 Cookie)
}
**九、替代方案**
如果浏览器存储不满足需求,可以考虑:
- **Cookie**:数据会随 HTTP 请求发送到服务器,但存储容量小(约 4KB)。
- **IndexedDB**:更强大的客户端数据库,支持存储大量结构化数据。
- **Web SQL**:已被弃用,不建议使用。
根据具体需求选择合适的存储方案,合理利用浏览器提供的存储机制可以提升用户体验和应用性能。