js localstorage 和 indexeddb 用法
【摘要】 在JavaScript中,localStorage 和 IndexedDB 是两种常用的客户端存储方案,分别适用于不同的场景。以下是它们的详细用法和对比: 1. localStorage 用法localStorage 是一个简单的键值对存储,数据以字符串形式保存,适合存储少量简单数据(如用户偏好、Token等)。 基本操作 存储数据// 存储字符串localStorage.setItem('...
在JavaScript中,localStorage 和 IndexedDB 是两种常用的客户端存储方案,分别适用于不同的场景。以下是它们的详细用法和对比:
1. localStorage 用法
localStorage 是一个简单的键值对存储,数据以字符串形式保存,适合存储少量简单数据(如用户偏好、Token等)。
基本操作
存储数据
// 存储字符串
localStorage.setItem('username', 'JohnDoe');
// 存储对象(需序列化为JSON字符串)
const user = { name: 'Alice', age: 25 };
localStorage.setItem('user', JSON.stringify(user));
读取数据
const username = localStorage.getItem('username'); // "JohnDoe"
const userData = JSON.parse(localStorage.getItem('user')); // { name: 'Alice', age: 25 }
删除数据
localStorage.removeItem('username'); // 删除指定键
localStorage.clear(); // 清空所有数据
遍历所有键
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}
注意事项
- 仅支持字符串:存储对象需用
JSON.stringify(),读取时用JSON.parse()。 - 同步操作:所有操作会阻塞主线程,不适合存储大量数据。
- 存储上限:通常为 5MB(不同浏览器可能略有差异)。
2. IndexedDB 用法
IndexedDB 是一个事务型数据库,支持结构化数据存储(如对象、二进制数据),适合存储大量复杂数据(如应用状态、离线数据)。
基本操作
1. 打开数据库
const request = indexedDB.open('MyDatabase', 1); // 数据库名和版本号
request.onerror = (event) => {
console.error('数据库打开失败:', event.target.error);
};
request.onsuccess = (event) => {
const db = event.target.result;
console.log('数据库打开成功');
};
// 首次创建或升级数据库时触发
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建对象存储空间(类似表)
if (!db.objectStoreNames.contains('users')) {
const store = db.createObjectStore('users', { keyPath: 'id' });
// 可选:创建索引
store.createIndex('name', 'name', { unique: false });
}
};
2. 增删改查(CRUD)
(1)添加数据
function addUser(user) {
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
const request = store.add(user);
request.onsuccess = () => console.log('用户添加成功');
request.onerror = (e) => console.error('添加失败:', e.target.error);
}
addUser({ id: 1, name: 'Alice', age: 25 });
(2)查询数据
function getUser(id) {
const transaction = db.transaction(['users'], 'readonly');
const store = transaction.objectStore('users');
const request = store.get(id);
request.onsuccess = (e) => console.log('查询结果:', e.target.result);
request.onerror = (e) => console.error('查询失败:', e.target.error);
}
getUser(1);
(3)更新数据
function updateUser(user) {
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
const request = store.put(user); // put 会覆盖同名键的数据
request.onsuccess = () => console.log('更新成功');
}
updateUser({ id: 1, name: 'Alice Updated', age: 26 });
(4)删除数据
function deleteUser(id) {
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
const request = store.delete(id);
request.onsuccess = () => console.log('删除成功');
}
deleteUser(1);
(5)遍历所有数据
function getAllUsers() {
const transaction = db.transaction(['users'], 'readonly');
const store = transaction.objectStore('users');
const request = store.getAll();
request.onsuccess = (e) => {
console.log('所有用户:', e.target.result);
};
}
3. 使用游标遍历数据
function cursorExample() {
const transaction = db.transaction(['users'], 'readonly');
const store = transaction.objectStore('users');
const request = store.openCursor();
request.onsuccess = (e) => {
const cursor = e.target.result;
if (cursor) {
console.log('当前记录:', cursor.value);
cursor.continue(); // 移动到下一条记录
}
};
}
4. 使用索引查询
function getUsersByName(name) {
const transaction = db.transaction(['users'], 'readonly');
const store = transaction.objectStore('users');
const index = store.index('name');
const request = index.getAll(name);
request.onsuccess = (e) => {
console.log('按姓名查询结果:', e.target.result);
};
}
注意事项
- 异步操作:IndexedDB 的所有操作都是异步的,需通过回调或
Promise处理。 - 事务(Transaction):所有读写操作必须在事务内进行。
- 存储上限:通常为 剩余磁盘空间的百分比(Chrome/Firefox)或 250MB(IE)。
- 复杂查询:支持索引和游标,但不如 SQL 直观。
3. localStorage vs IndexedDB 对比
| 特性 | localStorage | IndexedDB |
|---|---|---|
| 数据类型 | 仅字符串 | 支持对象、二进制数据(Blob、ArrayBuffer) |
| 存储上限 | 5MB | 浏览器差异大(通常数百MB到磁盘剩余空间) |
| 操作方式 | 同步 | 异步(基于事件或 Promise) |
| 适用场景 | 简单键值对(如用户设置) | 大型结构化数据(如应用状态、离线数据) |
| 查询能力 | 仅按键查询 | 支持索引、游标、范围查询 |
4. 封装 IndexedDB 为 Promise
由于 IndexedDB 是事件驱动的,可以封装为 async/await 风格:
class IDBWrapper {
constructor(dbName, version) {
this.dbName = dbName;
this.version = version;
this.db = null;
}
async init() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, this.version);
request.onerror = (e) => reject(e.target.error);
request.onsuccess = (e) => {
this.db = e.target.result;
resolve(this.db);
};
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains('users')) {
db.createObjectStore('users', { keyPath: 'id' });
}
};
});
}
async add(storeName, data) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.add(data);
request.onsuccess = () => resolve();
request.onerror = (e) => reject(e.target.error);
});
}
// 其他方法(get、put、delete等)类似...
}
// 使用示例
(async () => {
const idb = new IDBWrapper('MyDB', 1);
await idb.init();
await idb.add('users', { id: 1, name: 'Bob' });
})();
总结
localStorage:简单、同步、适合小数据。IndexedDB:强大、异步、适合大数据和复杂查询。- 推荐库:
localForage(封装 IndexedDB/WebSQL/localStorage,提供类似 localStorage 的 API)。Dexie.js(简化 IndexedDB 操作的轻量级库)。
根据需求选择合适的存储方案!
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)