data属性必须以data-开头且仅含小写字母、数字和连字符,连字符后可接数字但不可开头;值全为字符串,需手动类型转换;dataset非响应式,赋值应优先用el.dataset.key而非setAttribute;不适用于敏感信息或大量数据。

data属性必须以data-开头,且不能包含大写字母
HTML的data-属性是标准方式,浏览器会自动把连字符转成驼峰命名供JavaScript读取。比如data-user-id在JS里对应dataset.userId,而data-UserID或data-userId都不合法——解析后会变成userid或直接被忽略。
常见错误是手抖写成data_user_id(下划线)或dataUserID(没连字符),结果dataset里根本查不到这个键。
- 只允许小写字母、数字、连字符(-)和下划线(_)?错,下划线也不行,W3C规范明确只认连字符
- 连字符后紧跟数字(如
data-id2)可以,但data-2id不行——属性名不能以数字开头 - 值可以是任意字符串,包括空格、JSON字符串,但别直接塞对象字面量,得自己
JSON.parse()
用dataset读取时注意类型全是字符串
dataset返回的所有字段都是字符串,哪怕你写了data-count="42",读出来也是"42",不是数字。布尔值同理:data-active="true"读出来是字符串"true",不是true。
容易踩坑的是条件判断:if (el.dataset.active)对"false"也返回true,因为非空字符串都为真。要严格判断布尔语义,得显式转换:
立即学习“前端免费学习笔记(深入)”;
const active = el.dataset.active === 'true'; const count = Number(el.dataset.count) || 0;
-
dataset不支持嵌套对象,data-config='{"a":1}'读出来就是字符串'{"a":1}',需手动JSON.parse() - 如果值含单引号,写在HTML里要用双引号包裹属性,反之亦然,避免语法错误
- IE11支持
dataset,但旧版Edge有bug:带多个连续连字符(如data-foo--bar)会被截断
用setAttribute写入data属性时,dataset不会实时更新
直接调用el.setAttribute('data-foo', 'bar')确实能写入DOM,但已获取的dataset对象不会同步刷新——它是个快照,不是响应式代理。下次访问dataset.foo才会重新读取属性值。
所以别这么写:
el.setAttribute('data-status', 'done');
console.log(el.dataset.status); // 可能还是旧值,尤其在循环中反复读取时
- 安全做法是统一用
dataset赋值:el.dataset.status = 'done',它会自动同步到DOM属性 - 如果必须用
setAttribute(比如动态拼接属性名),之后再读就保险了,或者手动触发一次el.dataset重新获取 - 批量设置多个data属性时,
dataset逐个赋值比多次setAttribute略快,且更可读
data属性不适合存大量数据或敏感信息
它本质是公开的HTML源码一部分,任何用户都能右键“查看页面源代码”看到所有data-内容。别放token、密码、用户身份证号这类东西。
另外,存太多或太长的data值会显著增大HTML体积,影响首屏加载和内存占用。比如把整张表格JSON塞进data-table-data,不如用AJAX按需加载。
- 临时状态(如当前选中项ID、折叠状态)适合用data属性;持久化数据该走localStorage或后端API
- 值超过几KB时,考虑用
data-id只存索引,真实数据由JS模块管理 - 服务端渲染时,data属性是可靠的初始状态传递通道,但客户端接手后应尽快转为内部状态变量,减少对DOM的依赖



















