(Javascript) 1. Data type? -5- : Property, descriptor

김동우·2021년 6월 11일
2

wecode

목록 보기
8/32

잠깐! 시작하기 전에

이 글은 wecode 사전 스터디에서 실제 공부하고, 이해한 내용들을 적는 글입니다. 글의 표현과는 달리 어쩌면 실무와는 전혀 상관이 없는 글일 수 있습니다.

또한 해당 글은 다양한 자료들과 작성자 지식이 합성된 글입니다. 따라서 원문의 포스팅들이 틀린 정보이거나, 해당 개념에 대한 작성자의 이해가 부족할 수 있습니다.

설명하듯 적는게 습관이라 권위자 발톱만큼의 향기가 조금은 날 수 있으나, 엄연히 학생입니다. 따라서 하나의 참고자료로 활용하시길 바랍니다.

글의 내용과 다른 정보나 견해의 차이가 있을 수 있습니다.
이럴 때, 해당 부분을 언급하셔서 제가 더 공부할 수 있는 기회를 제공해주시면 감사할 것 같습니다.

Property

지난 글에서 우리는 Javascript의 Object를 구성하는 property와 Object의 자료구조인 Hash table에 대해 생각했습니다.

이번 시간에는 property에 대해 보다 깊은 얘기를 해봅시다.

(Data - Accessor) property

property의 경우 2가지의 형태로 코드 내에 존재하고 있습니다.

첫째, { 'key' : ( value 혹은 그보다 복잡한 구조체 ) } 쌍으로 이루어진 Data property

둘째, value를 포함하지 않는 Accessor property

이렇게 글만 보면 참 어려운 주제인 것 같습니다.

저 또한, value가 없는 property라는 표현이 와닿지 않기도 했습니다.

이제 천천히 해당 개념이 무엇인지 짚어보면서 글을 적어보겠습니다.

Data property

이전 포스팅에서 우리의 property의 코드는 아래와 같았습니다.


let obj = {
    name : `dongwu`,
    age : 26
  };

이제 확실히 key와 value가 눈에 들어오네요. 더군다나 확실히 해당 property가 어떤 내용들을 포함하고 있는지 코드만 봐도 확 느낌이 옵니다.

위처럼 name : 'dongwu' 쌍인 형태로 property를 결정할 때, 우리는 data property를 생성해냈다고 볼 수 있습니다.

data property는 실존하는 property인데, 후에 나올 가상의 property, Accessor property와는 달리 내부, 외부에서 모두 가시적으로 드러난다는 특성이 있습니다.

또한, 이전에는 다루지 않았던 새로운 개념들이 등장하게 됩니다.

바로 property attribute 입니다.

Accessor property를 생각해보기 전에 property attribute는 무엇인지 먼저 알아봅시다.

Data Property attribute

우리가 기존에 알고 있는 property, Data property의 경우 4가지의 attribute를 가지고 있습니다.

이 중 3개는 다른 말로 flag로 표현합니다.

flag는 일종의 switch(on/off) 역할을 하는데, Boolean 값을 입력받음으로 특정 기능을 수행할 수 있는지의 여부를 결정합니다.

value

  • key에 해당하는 값. data 그 자체입니다.

flag

  • writable = (true or false) : 값의 변경여부
  • enumerable = (true or false) : 연산(반복문)의 가능 여부
  • configurable = (true or false) : property 자체 삭제 혹은 수정 여부, 다른 flag의 수정(on/off) 여부.

오브젝트 내의 property를 기존의 방식으로 선언했다면, Data property 내의 flag는 전부 true(on)의 상태가 됩니다.

그러나 Object.defineProperty(obj, propertyName, {value}) 와 동일하게 Data property를 생성할 경우, flag는 전부 false(off)의 상태가 됩니다.

이를 극복하기 위해서는 {value} 외에 다양한 flag 설정을 직접 해주어야 합니다.

이러한 내용을 확인하기 위해서 우리는 특정 메서드를 활용해야 합니다.

또한, 위 메서드를 우리는 Property Descriptor 라고 부르게 됩니다.

거기다 property의 종류를 따와서 Data Descriptor 라는 표현을 사용하기도 합니다.

초반부의 개념을 이해하기 위한 해당 글에서는 자세한 메서드 종류와 기능에 대해서 다루지는 않겠습니다.

Accessor property

먼저, 기존과 달리 새로운 방식으로 property를 만들어보겠습니다.


let obj = {
  _name : 'dongwu',
  _surname : 'Kim',
      			
  get fullName() {
    return `${this._name} ${this._surname}`;
  },
  
  set fullName(value) {
    [this._name, this._surname] = value.split(" ");
  }

};

console.log(obj.fullName); // output : dongwu Kim

obj.fullName = 'wudong Kim';
console.log(obj._name); // output : wudong
console.log(obj._surname); // output : Kim
console.log(obj.fullName); // output : wudong Kim

새로운 property가 둘 생겼습니다. 심지어 get fullName(){} 이라는 함수의 형태로 이루어져 있네요.

위 함수를 거쳤더니 외부에서는 obj 내부에 fullName : 'dongwu Kim' 이라는 property가 존재하는 것으로 보이게 됩니다.

get

이처럼 get 함수(getter 메서드)를 통해 property가 가상으로 생성될 경우, Accessor property 라고 표현합니다.

실제로 내부에서 fullName이라는 property를 key-value의 형태로 생성하지 않았음에도 우리는 해당 property를 읽고, 쓸 수 있습니다.

set

수정하는 방법은 set(setter 메서드) 함수를 사용해서 가능합니다.

위 코드에서 obj.fullName = 'wudong kim' 구문 이후 _name과 _surname의 value가 수정되는 것을 output에서 확인할 수 있습니다.

이처럼 가상의 property인 fullName을 만들어내기 위해 실존하는 property인 _name, _surname이 사용된다는 사실은 약간 어지럽긴 합니다.

또한, setter 메서드가 obj 내부의 data property인 _name 과 _surname의 값을 바꿔버릴 수 있는 힘을 가졌다는 점이 말로는 형용할 수 없는 어떤 기분을 맛보게 합니다.

지난 시간의 내용을 연관지어보면, const 로 obj 를 선언할 경우 위와 같은 코드의 실행은 불가능합니다. 이미 선언된 객체의 내용을 바꿀 수 없기 때문이죠.

자, 이제는 Accessor property의 attribute와 flag를 다뤄봅시다.

Accessor property attribute

이전 단계에서 말했듯, Accessor property의 경우 가상의 값을 다룹니다. 실체가 존재하지 않기 때문에 value와 writable에 해당하는 attribute는 존재하지 안습니다.

function

  • get : property를 read, 단순 호출할 때 동작합니다. 선언 시 parameter를 요구하지 않습니다.
  • set : property를 write, 수정할 때 동작합니다. 선언 시 parameter를 하나 요구합니다.

flag

  • enumerable = (true or false) : 반복문의 사용 여부를 결정합니다
  • configurable = (true or false) : flag 수정, property의 삭제 여부를 결정합니다.

이러한 속성을 확인하기 위해서는 property descriptor를 이용해야 하는데, Data property와 동일하게 Object.getOwnPropertyDescriptor(obj, prop) 메서드를 활용하면 됩니다.

또한 Object.defineProperty(obj, propertyName, {get(), set()}) 와 같은 방식으로 메서드를 활용하면 Accessor property의 flag 또한 직접 초기에 설정할 수 있습니다.

주의해야 할 점은 configurable = false 의 경우 이후 어떤 코드를 첨가하더라도 flag의 수정이 아예 불가능하게 됩니다.

따라서, 코드 내에서 특수한 상황을 제외한 대부분의 상황에는 configurable = true를 먼저 적어주시기 바랍니다.

마치며

이제 property의 종류, 그리고 Object의 구조가 머리에 어느정도 자리를 잡은 것 같습니다.

후에 set과 get은 무언가 React의 state를 다루는 메서드와 비슷한 구석이 있지 않을까 하는 생각도 가질 수 있었던 것 같습니다.

다음 글은 조금 생각한 뒤에 내용을 결정할 것 같지만, 아무래도 Array에 대한 내용 혹은 function에 대한 내용을 정리한 뒤 실습으로 넘어가야 할 것 같다고 생각하고 있습니다. (둘 다 Object의 하위개념으로 분류되기 때문입니다.)

자기소개 페이지를 수정하면서 이전에 Js에서 사용했던 이미지 처리기법이나 async-await, 또는 다뤄본 적 없던 클로저의 개념까지 한 번 사용해봐야 하지 않을까 생각합니다.

이상으로 Object - property에 대한 노트를 끝내도록 하겠습니다. 부족한 글 읽어주셔서 감사합니다.

참고자료

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#
https://ko.javascript.info/property-descriptors
https://velog.io/@longroadhome/%EB%AA%A8%EB%8D%98JS-%EA%B0%9D%EC%B2%B4-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EC%84%A4%EC%A0%95
https://velog.io/@doondoony/JavaScript-Object#-property-name
https://negabaro.github.io/archive/js-property
https://medium.com/sjk5766/javascript-object-%ED%83%90%EA%B5%AC%EC%83%9D%ED%99%9C-7bc906cc377c
https://moonscode.tistory.com/6

이후 읽어봐야 할 자료

https://m.blog.naver.com/magnking/220966405605

1개의 댓글

comment-user-thumbnail
2021년 6월 15일

최...최고

답글 달기