...
Attribute vs Property 정의 차이
attribute 와 property 를 한국어로 번역하자면 둘다 '속성' 이라는 의미를 가지고 있다. 단순히 단어명이 같은 것을 떠나서 실제로 둘은 html 요소에 대한 클래스와 아이디와 같은 속성을 가리킨다. 이처럼 어트리뷰트와 프로퍼티의 둘은 같은 의미를 내포하지만, 웹 프로그래밍에서 이 둘은 구체적인 차이점이 존재 한다.
HTML의 Attribute
어트리뷰트는 HTML의 속성이다. 엘리먼트에 아이디나 클래스와 같은 추가적인 정보를 일컫는다고 보면 된다
<!-- div 엘리먼트의 id와 class 속성은 어트리뷰트 이다 -->
<div id="inpa" class="bold"></div>
<!-- input 엘리먼트의 type과 value 속성은 어트리뷰트 이다 -->
<input type="text" value="0">
DOM의 Property
프로퍼티는 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>
위 트리는 <div class= ‘my-class’></div> 태그를 DOM 으로 표현한 것인데 위에서 className이 property가 되는 것으로 보면 된다. div 태그 안에 class="이름" 으로 되어있는데 className 속성명으로 접근해서 설정할 수 있는 이유는 어트리뷰트와 프로퍼티가 비록 이름은 다를지라도 서로 연결되어있어서 그렇다.
DOM은 HTML을 자바스크립트 객체(Object)로 표현한 문서 모델이라고 보면 된다. 그래서 자바스크립트로 HTML 구조의 부분과 통신하고, 업데이트하고, 생성하고, 삭제하는 행위를 할 수 있다.
Attribute vs Property 기능 차이
엘리먼트 속성 접근 차이
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 가 아닌 undefined 라는 결과값을 내뱉는다.
const input = document.querySelector('input');
console.log(input.custom); // undefined
이러한 사용자 정의 속성 값에 접근하려면 getAttribute() 와 setAttribute()를 사용하면 된다.
console.log(input.getAttribute('custom')); // '9999'
속성 이름 제약사항
프로퍼티는 자바스크립트 객체 이기 때문에 프로퍼티 이름은 점(.)연산자 표기법을 사용하는 식별자로 간주되고, 식별자 규칙을 따라야해서 프로퍼티명을 이름 짓는데 제약이 있다. 예를들어 어트리뷰트는 background-image 와 같이 - 문자를 사용해도 되지만, 프로퍼티는 변수명 규칙에 따라야 하기 때문에 backgroundImage 로 접근해야 된다.
const div = document.querySelector('div');
// 프로퍼티
div.style.backgroundImage = 'url()';
// 어트리뷰트
div.setAttribute('style', 'background-image: url()');
프로퍼티 이름과 속성 이름이 서로 다른 몇몇 예로는, class/className , readonly/readOnly, maxlength/maxLength 등이 있다. 예약어인 경우 className 처럼 다른 이름이 존재하고, 여러 단어로 이루어진 속성이름인 경우 낙타 표기법(CamelCase)을 사용해서 표현된다.
성능 차이
일반적으로 프로퍼티 접근이 getAttribute() 와 setAttribute() 메서드보다 약간 더 빠르다. 따라서 사용자 정의 속성과 같이 별도의 프로퍼티가 없는 경우에만 메서드를 이용하고 그외에는 프로퍼티로 접근하는 방법이 이상적이라 볼 수 있다.
# 참고자료
https://ultimatecourses.com/blog/attributes-versus-properties-in-javascript
https://medium.com/hexlant/attribute-%EC%99%80-property-%EC%9D%98-%EC%B0%A8%EC%9D%B4-c6f1c91ba91
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.