-
새로운 객체 기능Web/자바스크립트 2023. 4. 15. 17:46
아래 내용은 웹 개발자를 위한 자바스크립트의 모든 것 5장을 읽고 정리한 내용입니다.
계산 된 속성 이름
이미 제공하던 기능을 좀 더 쉽게 제공하는 것으로, 속성 명을 지정된 이름이 아닌 연산으로 나온 결과로 생성하는 기능.
별거 아닌 것 같지만, spread 연산자와 함께 쓸 경우 좀 더 간편하게 작성될 수 있어서 좋다. 예제의 calc 같은 변수 또한 실제로는 생성한다기 보다는 선택된 값을 사용하는 경우가 더 많을 것 같다.let calc = 2 + 3; let obj = { [calc] : 4 }
단축 속성
불 필요한 타이핑을 줄일 수 있는 방식인데, 한 편으로는 이 값이 이 값이 맞나 하는 오해가 생기는 때도 있다.
물론 그런 오해로 안 쓰기에는 너무도 편하고 오타를 줄일 수 있는 방법이다.let min, max; return {min, max} // 기존 : {min: min, max:max}
메서드 문법과 super 외부 클래스
메서드 문법이라는 단어가 꽤 어렵다. 작성된 것도 크게 이전과 다른 것 같지 않지만 꽤 큰 차이가 있다.
let obj = { func: function () { console.log(‘hello, world’); } } leb obj = { method() { console.log(‘hello, world’); } }
위의 예제를 보면 약간은 말장난 같아 보이기도 하다. 뭐 콜론과 function을 덜 쓰니까 좋은가 싶지만, 생각보다 큰 차이가 있따.
일단, method()라고 명명한 메소드 구문은 prototype 속성이 없으므로 생성자 사용이 불가하다.
4장의 클래스를 참고하면 function Color() {…} -> let c = new Color() 이렇게 사용하는 것이 불가하다는 말그보다 더 큰 차이는 메서드 구문은 메서드가 정의되어 있는 객체에 대한 링크를 가지고 있다. 위의 예제에서 보면 method()는 obj를 알고 있다는 뜻이다.
이게 중요한 것은 클래스의 super와 연결이 되는데, 내가 호출되고 있는 객체를 알고 있으니 그 객체가 상속하고 있는 객체도 타고 갈 수 있게 되는 것이다.class Base { test() {} } class A extends Base { test() { super.test();} }
위와 같은 코드를 생각하면 test가 메서드 함수가 아니라면, A 라는 객체의 존재를 알 수가 없으니 super를 통해 A가 상속받은 Base 객체 또한 알 수가 없다. 그렇기 때문에 super 라는 것이 동작할 수가 없다.
하지만 메서드 함수 이기 때문에 A 객체의 링크를 가지고 있고 이를 통해 A 로부터 Base를 알고 Base를 super로 인지해서 super.test 호출이 가능해 진다.당연히 이 메서드 함수는 위의 ‘계산 된 속성 이름’ 규칙이 적용되며, 문자열 또한 가능하다. (예) ‘abc’() 혹은 1+2 -> 이 경우 메서드의 실질 이름은 3()
심볼 in 자바스크립트
심볼이 대단한 것이라는 생각을 했는데…! 그렇지 않다.
심볼은 속성에 대한 “키” 값
이름과 키를 혼돈하는 것을 방지하기 위해 책에서는 이름과 키는 다르다는 얘기를 적어 두었는데 이름과 키는 다르다는 말만 보면 왜 이런 얘기를 하지? 싶다. 확실히 책이 기본서가 아니다보니 어려운 내용을 나름 쉽게 설명을 하는 데도 이해하는데 어려움이 있다.
속성에 대한 키 라는 말을 이해하기 위해서는 무엇이 “키”인가 라는 것부터 이해를 해야 할 것 같다.
아래 예제를 보면 1+2, ‘test’, abc 각각이 obj 객체의 속성이라고 볼 수 있는데 이 속성을 식별(구분) 하기 위한 것을 ‘키’라고 부른다.
이름과 다른 가 ? 라고 묻는다면 1+2는 계산 된 값이므로, “1+2가 계산된 값”을 이름이라고 부르긴 어려울 것이다. 그래서 문자 열로 된 (아래 예제에서는 test인 것만) 속성의 키 값을 속성 이름이라고 한다. 하지만 책에서도 적혀 있듯이 큰 의미는 없으니 키와 이름에 집착할 필요는 없을 것 같다.
⭐ 중요한 것은 속성을 ”식별”할 수 있는 무엇인가가 있어야 하고, 이렇게 식별 할 수 있는 키를 직접 작성할 수도 있지만 “심볼을 사용 할 수도 있다“라는 것이다.let obj = { [1+2]: ‘haha’, ‘test’: 3, abc() { console.log(‘hello, world’); } }
그래서 심볼이 왜 필요한데 ?
다른 언어를 써봤다면 간혹 Unique를 생성해야 하는 일들이 생긴다. 예를 들면, 파일의 진짜 이름이 아닌 어떤 식별 가능한 코드로 보여주고 싶을 때. 그럴 때 절대 겹치지 않는 뭔가를 만들어 내야 하는 스트레스를 줄이기 위해 GUID 같은 것을 사용한다.
심볼 또한 그런 용도로 사용이 가능하다.
고유한 키를 ‘생성’해서 쓸 일이 있을까
실무에서 심볼을 생성해서 뭔가를 할 일이 있을 지는 이제 막 접하였기 때문에 실용성은 모르겠다. 다만, 이미 생성된 심볼을 이용하는 것은 유의미 하다.
왜 때문인지 모르겠지만 toString을 할 때 내가 만든 클래스 이름이 Object라고 뜨는 것이 마음에 안들까봐 바꿀 수 있게 해둔 것이 symbol.toStringTag 이다.get [Symbol.toStringTag] () { return “new toString”; }
사용 방법은 위와 같다. 내가 만든 객체는 “이미” toString이라는 속성을 가지고 있다. 이 toString 속성은 객체를 출력해서 보여주는 데 내가 만든 객체는 당연히 뭔지 알 수 없으니 단순하게 ”[object Object]“ 이렇게 호출이 될 것이다. 여기서 Object 라는 부분을 원하는 값으로 바꾸고 싶으면 위의 toStringTag를 재정의 하면 된다.
이렇게 봐서는 단순히 toString 재정의 하는게 뭐 그리 의미가 있을까 싶겠지만 잘 알려진 더 좋은 심볼들이 있으니 좀 더 다른 활용도가 있지 않을까 싶다. 이미, 클래스 단계에서 배운 Symbol.species를 통해 생성자를 재 정의할 수 있음을 배웠으니 심볼 자체에 대한 공부는 차차 확장 될 것 같다.
심볼 사용 상 주의 점
- 불완전한 클래스이기 때문에 new를 하지 않는다.
- 속성의 ‘이름’이 아닌 ‘키’이기 때문에 getOwnPropertyNames 메서드로 조회가 불가하다. (getOwnPropertySymbols로 가능)
- JSON.stringify 시, 무시된다.
심볼 생성 / 조회
Symbol(”심볼 키“) // 생성 Symbol.for(“심볼 키“) // 전역 심볼을 검색하고 있으면 반환, 없으면 생성 Symbol.keyFor(심볼) // 전역 심볼이 있다면 키 값을 반환, 없으면 Undefined
당연하겠지만, 전역으로 심볼을 만들 때에는 시스템 내에 중복이 되지 않도록 하는 것이 필요하다
Symbol.toPrimitive
책에서 하나의 섹션으로 다룬 부분이라 좀 더 찾아보았는데 아래 링크가 정말 엄청나게 잘 정리되어 있어서 대체!
https://ko.javascript.info/object-toprimitive
객체를 원시형으로 변환하기
ko.javascript.info
'Web > 자바스크립트' 카테고리의 다른 글
Day 5. Are they the "same"? [6kyu] (0) 2023.03.05 Javascript 클래스 (0) 2023.03.04 화살표 함수 (0) 2023.02.11 let 과 const (2) 2023.02.06