attribute 与 property 的区别

HTML 属性与 DOM 属性的区别和联系

问题

HTML 中的 attribute 和 DOM 中的 property 有什么区别?

解答

基本概念

Attribute 是 HTML 标签上定义的属性,Property 是 DOM 对象上的属性。

<input id="username" type="text" value="hello">
const input = document.getElementById('username');

// 获取 attribute(HTML 属性)
input.getAttribute('value');  // "hello"

// 获取 property(DOM 属性)
input.value;  // "hello"

初始化关系

页面加载时,浏览器会解析 HTML,将 attribute 映射为对应的 property:

const input = document.getElementById('username');

// 标准属性会自动映射
console.log(input.id);        // "username" (property)
console.log(input.type);      // "text" (property)

// 自定义属性不会映射为 property
// <div id="box" data-custom="abc" my-attr="xyz">
const div = document.getElementById('box');
console.log(div.dataset.custom);     // "abc" (data-* 有特殊处理)
console.log(div['my-attr']);         // undefined
console.log(div.getAttribute('my-attr')); // "xyz"

值的同步差异

这是最重要的区别。以 inputvalue 为例:

const input = document.getElementById('username');

// 初始状态
console.log(input.getAttribute('value')); // "hello"
console.log(input.value);                  // "hello"

// 用户在输入框中输入 "world"
console.log(input.getAttribute('value')); // "hello" (不变!)
console.log(input.value);                  // "world" (变了)

// 通过 property 修改
input.value = 'test';
console.log(input.getAttribute('value')); // "hello" (还是不变)
console.log(input.value);                  // "test"

// 通过 attribute 修改
input.setAttribute('value', 'new');
console.log(input.getAttribute('value')); // "new"
console.log(input.value);                  // "test" (不变!已经脱钩了)

不同属性的同步规则

// 1. id、class 等:双向同步
div.id = 'newId';
console.log(div.getAttribute('id')); // "newId"

div.setAttribute('id', 'anotherId');
console.log(div.id); // "anotherId"

// 2. input.value:attribute 是初始值,property 是当前值
// 修改 property 不影响 attribute

// 3. checkbox 的 checked
const checkbox = document.querySelector('input[type="checkbox"]');
checkbox.checked = true;  // property
console.log(checkbox.getAttribute('checked')); // null 或 "checked"(取决于 HTML)

// 4. href:property 返回完整 URL
// <a id="link" href="/path">
const link = document.getElementById('link');
console.log(link.getAttribute('href')); // "/path"
console.log(link.href);                  // "https://example.com/path" (完整 URL)

// 5. disabled:property 是布尔值,attribute 是字符串
// <button disabled>
button.disabled;                    // true (boolean)
button.getAttribute('disabled');    // "" (空字符串)

类型差异

// attribute 始终是字符串
input.getAttribute('maxlength');  // "10" (字符串)

// property 可以是任意类型
input.maxLength;  // 10 (数字)

// style 属性
div.getAttribute('style');  // "color: red;" (字符串)
div.style;                   // CSSStyleDeclaration 对象

关键点

  • Attribute 定义在 HTML 中,通过 getAttribute/setAttribute 操作,值始终是字符串
  • Property 是 DOM 对象属性,通过 . 操作,值可以是任意类型
  • 标准属性初始化时会从 attribute 映射到 property,但后续同步规则因属性而异
  • input.value 的 attribute 代表初始值,property 代表当前值,两者独立
  • 操作 DOM 时优先使用 property,更直观且类型正确