어트리뷰트는 HTML의 속성이다. 엘리먼트에 아이디나 클래스와 같은 추가적인 정보를 일컫는다고 보면 된다.
<!-- div 엘리먼트의 id와 class 속성은 어트리뷰트 이다 -->
<div id="inpa" class="bold"></div>
<!-- input 엘리먼트의 type과 value 속성은 어트리뷰트 이다 -->
<input type="text" value="0">
프로퍼티는 DOM의 속성이다. 즉, html의 attribute를 DOM 내에서 대신해서 표현이라고 보면 된다.
<div class='my-class' style="color: red;"></div>
<script>
// className과 style은 프로퍼티이다
document.querySelector('div').className; // "my-class"
document.querySelector('div').style.color; // "red"
</script>
attribute는 html 안에서 property는 DOM tree 안에서 존재한다. 이것이 뜻하는 바는 attribute는 정적으로 변하지 않고 property는 동적으로 그 값이 변할 수 있다는 의미를 내포하고 있다. 예를 들어 체크 박스 태그가 있을 때 유저가 체크박스에 체크를 하면 attribute의 상태는 변하지 않지만 property의 상태는 checked로 변하게 된다.
아래 input 태그가 있고 value 어트리뷰트로 0 값을 가지고 있다.
<input type="text" value="0">
이를 자바스크립트 DOM 문법을 통해서 input 엘리먼트에 접근해 value 속성 값을 가져올 수 있다. 여기서 input.value는 프로퍼티이다.
const input = document.querySelector('input');
console.log(input.value); // '0'
이번엔 value 속성값을 임의의 값으로 변경해보자. input.value의 값을 재설정하고 다시 확인해보면 변경된 값으로 설정 되었음을 확인할 수 있다.
input.value = 66;
console.log(input.value); // '66'
그런데 HTML 태그를 보면 여전히 value의 값은 0인채 그대로 있는걸 볼 수 있다.
위에서 말한 어트리뷰트는 정적이고 프로퍼티는 동적 이라는 말이 바로 이것이다. 어트리뷰트와 프로퍼티는 둘이 연결되어 있긴 하지만 엄밀히 다른 녀석이라, 프로퍼티의 값을 변경해도 DOM객체만 업데이트 되고 HTML은 업데이트 되지 않아 어트리뷰트의 값은 그대로 인 것이다.
💡 DOM은 JavaScript 모델이므로 굳이 HTML 속성을 계속 업데이트할 필요가 없다. 실제로 리소스 낭비가 될 수 있어 이런식으로 설계 되었다고 보면 된다.따라서 DOM과 HTML 둘다 특정 속성에 대해 값을 변경하고 싶다면, setAttribute() 메서드를 통해 업데이트 해주면 된다.
const input = document.querySelector('input');
input.setAttribute('value', 99);
console.log(input.value); // '99'
HTML에 미리 정의된 태그의 속성 뿐만 아니라 개발자가 임의로 엘리먼트에 사용자 정의 속성을 만들어 넣을 수도 있다.
<!-- 실제 html에 없는 사용자 정의 임의 속성 custom -->
<input type="text" value="0" custom="9999">
그런데 프로퍼티의 특징으론 엘리먼트가 가진 모든 속성이 프로퍼티로 되지는 않다는 점이다. HTML에 지정된 속성들은 프로퍼티로도 표현되지만, 엘리먼트에 임의로 지정한 사용자 정의 속성은 프로퍼티로 자동으로 표현되지 않는다. 실제로 자바스크립트로 접근해보면 9999가 아닌 undegined라는 결과괎을 내뱉는다.
const input = document.querySelector('input');
console.log(input.custom); // undefined
이러한 사용자 정의 속성 값에 접근하려면 getArrtibute()와 setAttribute()를 사용하면 된다.
console.log(input.getAttribute('custom')); // '9999'
일반적으로 프로퍼티 접근이 getAttribute() 와 setAttribute() 메서드보다 약간 더 빠르다. 따라서 사용자 정의 속성과 같이 별도의 프로퍼티가 없는 경우에만 메서드를 이용하고 그외에는 프로퍼티로 접근하는 방법이 이상적이라고 볼 수 있다.