HTML 속성 vs DOM 프로퍼티

DOM 프로퍼티란?

브라우저가 HTML을 파싱할 때, 각 요소는 자바스크립트 객체로 변환됩니다. 이때 표준 HTML 속성들은 DOM 프로퍼티로 자동 생성됩니다. 예를 들어, 다음 HTML 코드가 있을 때:

<div id="main" class="container">Content here</div>

브라우저는 이를 아래와 같이 DOM 객체의 프로퍼티로 만듭니다

// DOM에서 접근하는 예
const mainDiv = document.getElementById('main');
console.log(mainDiv.id);       // "main"
console.log(mainDiv.className); // "container"

DOM 객체는 일반 자바스크립트 객체이므로, 새로운 프로퍼티나 메서드를 자유롭게 추가할 수 있습니다.

// 사용자 정의 프로퍼티 추가
document.body.myInfo = { author: "Jane Doe", version: "1.0" };
console.log(document.body.myInfo.version); // "1.0"

// 메서드 추가
document.body.showTag = function() {
  console.log(`This element is a ${this.tagName}`);
};
document.body.showTag(); // "This element is a BODY"

HTML 속성

HTML 코드에 작성된 속성(attribute)은 브라우저가 파싱할 때 DOM 프로퍼티로 변환되지만, 모든 속성이 반드시 프로퍼티로 자동 매핑되지는 않습니다.

표준 속성

예를 들어, <input>, <div>, <a> 등 대부분의 HTML 요소는 id, class, src, href 등의 표준 속성을 가지고 있고, 이들은 DOM 프로퍼티로 자동 생성됩니다.

<input id="agree" type="checkbox" checked>
<script>
  const checkbox = document.getElementById('agree');
  console.log(checkbox.checked);            // true (불린 값)
  console.log(checkbox.getAttribute('checked')); // 빈 문자열 ("") – 속성 값은 항상 문자열입니다.
</script>

비표준 속성

HTML에 직접 작성한 비표준 속성은 DOM 프로퍼티로 자동 생성되지 않습니다. 이런 경우에는 getAttribute와 setAttribute를 사용하여 접근해야 합니다.

<div id="info" custom-data="extra"></div>
<script>
  const infoDiv = document.getElementById('info');
  console.log(infoDiv.customData);                // undefined (비표준 속성은 자동 매핑되지 않음)
  console.log(infoDiv.getAttribute('custom-data')); // "extra"
  
  // 속성 값은 항상 문자열입니다.
  infoDiv.setAttribute('custom-data', 123);
  console.log(infoDiv.getAttribute('custom-data')); // "123"
</script>

data-* 속성과 dataset

HTML5에서는 사용자 정의 데이터를 안전하게 저장하기 위해 data- 접두사를 사용합니다. 이 속성들은 DOM 프로퍼티 dataset으로 자동 매핑되며, 카멜 표기법으로 변환됩니다.

<div id="profile" data-user-name="Alice" data-user-age="30"></div>
<script>
  const profile = document.getElementById('profile');
  console.log(profile.dataset.userName); // "Alice"
  console.log(profile.dataset.userAge);  // "30"
  
  // 속성 수정은 dataset을 통해 간편하게 할 수 있습니다.
  profile.dataset.userName = "Bob";
  console.log(profile.getAttribute('data-user-name')); // "Bob"
</script>

속성과 프로퍼티의 동기화

표준 HTML 속성이 변경되면 대응하는 DOM 프로퍼티도 자동으로 갱신됩니다.

<input id="input1" value="initial">
<script>
  const inputElem = document.getElementById('input1');

  // 속성을 변경하면 프로퍼티도 갱신됨
  inputElem.setAttribute('value', 'changed');
  console.log(inputElem.value); // "changed"

  // 반대로 프로퍼티를 변경하면, getAttribute로 읽으면 원래의 값이 남는 경우도 있습니다.
  inputElem.value = "new value";
  console.log(inputElem.getAttribute('value')); // 여전히 "changed"
  // 이 예외는 특히 value 속성처럼 동적으로 변경되는 경우에 주의해야 합니다.
</script>

일반적으로 표준 속성은 동기화되지만, 일부 경우(예: <input>의 value)는 단방향(속성 → 프로퍼티) 동기화가 일어납니다.