<p>HTML 的 data-* 属性只能存储字符串,存数组必须用 JSON.stringify() 序列化、JSON.parse() 反序列化,并配合 try/catch 和空值判断;直接赋值数组会触发 toString() 导致结构丢失,dataset 读写有代理陷阱,应优先使用 setAttribute/getAttribute。</p>

HTML 的 data-* 属性不能直接存数组,必须序列化为字符串;最安全可靠的方式是用 JSON.stringify() 写入、JSON.parse() 读取,并始终配合 try/catch 和空值判断。
data-* 属性只认字符串,数组会自动 toString() 丢结构
你写 el.dataset.items = [1, 2, 3],浏览器实际存的是 "1,2,3",不是 JSON 数组。嵌套对象、null、布尔值全被扁平化或静默丢弃。
- 常见错误现象:
JSON.parse(el.dataset.config)报错SyntaxError: Unexpected token o,因为实际值是"[object Object]" -
toString()、join()、手拼字符串都不可靠——它们无法还原原始类型和嵌套结构 - 只有
JSON.stringify()能在 JSON 支持范围内保结构(不支持undefined、Date、function、RegExp) - 写入前建议校验数据:
if (typeof data === 'object' && data !== null) { ... }
dataset.xxx 读写有陷阱,优先用 setAttribute + getAttribute
dataset 是只读代理,赋值如 el.dataset.items = JSON.stringify([...]) 不会真正更新 DOM 属性节点,刷新后就丢失;且属性名不规范时(含数字、大写、下划线)会静默失败。
- 正确写入方式:
el.setAttribute('data-items', JSON.stringify([1, 2, 3])) - 更稳妥读取方式:
const raw = el.getAttribute('data-items');,再raw ? JSON.parse(raw) : [] - 避免混用:
el.dataset.items = 'xxx'后再el.setAttribute('data-items', 'yyy'),会导致dataset.items和getAttribute返回不同值 - 含数字开头的属性(如
data-2024-list)只能用getAttribute('data-2024-list'),dataset["2024List"]才能访问,dataset.2024List是语法错误
JSON 存取必须加 try/catch 和默认值兜底
用户输入、服务端注入或手动编辑 HTML 都可能导致 data-* 值不是合法 JSON,JSON.parse() 会直接抛错中断逻辑。
立即学习“前端免费学习笔记(深入)”;
- 不要裸调
JSON.parse(el.getAttribute('data-config')) - 标准写法:
const raw = el.getAttribute('data-config'); let config = {}; try { config = raw ? JSON.parse(raw) : {}; } catch (e) { console.warn('Invalid JSON in data-config:', raw, e); } - 空值判断不能只靠
|| {}:如果raw === "null"或"undefined",JSON.parse(raw)仍会报错 - 服务端预渲染时,确保输出的 JSON 已被
JSON.stringify()处理并 HTML 实体转义(防 XSS),尤其当值含用户输入时
真正容易被忽略的是:data-* 不是状态容器,它只适合存轻量、静态、与元素生命周期一致的元数据;数组一旦变大或需跨刷新保留,就得换 localStorage 或 IndexedDB——别等页面重载后发现数据没了才回头改架构。



















