data-*属性存数字须转类型、规范命名、处理边界;属性名全小写+连字符,dataset自动转驼峰,返回值恒为字符串,需手动转换;修改必须用setAttribute,调试优先用getAttribute。

data-* 属性里存数字,别直接塞字符串就完事——不转类型、不规范命名、不处理边界,后续 JS 一算就错。
data-* 属性名必须全小写+连字符,否则 dataset 读不到
浏览器只认 data-price、data-stock-count 这种写法。写成 data-Price、data_stock_id 或 data-2024count,element.dataset.price 就返回 undefined。
-
data-user-id→ 可用el.dataset.userId -
data-sale-rate→ 对应el.dataset.saleRate(自动转驼峰) -
data-user_id→el.dataset.userId是undefined,得用el.getAttribute('data-user_id') -
data-2024-id→ 点号访问失效,必须用el.dataset["2024Id"]
dataset 返回的永远是字符串,数字/布尔必须手动转
哪怕你写 data-price="199.99" 或 data-active="false",JS 里拿到的仍是 "199.99" 和 "false",不是数字或布尔值。
- 数字:用
Number(el.dataset.price)或parseFloat(el.dataset.price),别用+隐式转换(+"199.99abc"会得199.99,但+"abc"是NaN) - 布尔:用
el.dataset.active === 'true',别用Boolean(el.dataset.active)("false"会被转成true) - JSON 数据:先
el.dataset.config || 'null',再JSON.parse(),并加try/catch防崩溃
写入 data 属性必须用 setAttribute,dataset 赋值不保证同步到 DOM
el.dataset.count = '5' 看似改了,但 el.outerHTML 或 DevTools 里看不到变化——因为 dataset 是只读缓存视图,不是实时 DOM 映射。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确写法:
el.setAttribute('data-count', '5') - ✅ 删除属性:
el.removeAttribute('data-count') - ❌ 危险混用:
el.dataset.count = '5'后又el.setAttribute('data-count', '6'),此时el.dataset.count仍为'5' - 调试时验证是否生效,优先用
el.hasAttribute('data-count') && el.getAttribute('data-count')
表格或列表中高频读写 data 数字时,注意性能和重排
遍历几十行 <tr> 并反复读 td.dataset.price,可能触发 Layout Thrashing,尤其在循环中直接用于计算或样式更新。
- 先批量读取到局部变量:
const prices = Array.from(rows).map(r => Number(r.dataset.price)) - 避免在
for循环里反复调用el.dataset.xxx,DOM 访问开销比普通对象属性高得多 - 别把整组数据塞进单个
data-orders字符串——超长文本拖慢 DOM 解析,改用Map或 JS 对象缓存 - 懒加载场景下,等元素进入视口后再解析
dataset,防止预渲染阶段无效计算
最常被忽略的一点:服务端渲染(SSR)或模板引擎输出的 HTML 中,dataset 不可用——它依赖 DOM 解析完成,此时只能靠 getAttribute() 安全读取;而前端框架(如 React/Vue)对 data- 的处理逻辑也不完全一致,跨环境时建议统一用 getAttribute + 显式类型转换兜底。



















