반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • item8
  • item7
  • 토비의 스프링
  • 싱글톤
  • bean Validation
  • NEXT JS
  • 작업기억공간
  • 자료구조
  • 도커공식문서
  • 싱글턴
  • 메이븐 라이프사이클
  • 빈 검증
  • next js app
  • Next.js
  • 이펙티브 자바
  • 자바 검증
  • try-with-resources
  • 싱글톤 패턴
  • Javadoc 자바독 자바주석 주석 Comment
  • 이펙티브자바
  • 팩터리 메서드 패턴
  • 외래키 제약조건
  • 추상 팩터리 패턴
  • 자바스크립트 면접
  • 자바 디자인패턴
  • Java
  • rust
  • 객체복사
  • pnpm
  • prerendering
  • 메이븐 페이즈
  • 느린 쿼리
  • item9
  • 서버리스 컴퓨팅
  • 플라이웨이트패턴
  • 참조 해제
  • 자바
  • serverless computing
  • 자바스크립트
  • 프로그래머의 뇌
  • 자바스크립트 인터뷰
  • MSSQL
  • 러스트
  • 메이븐 골
  • Pre-rendering
  • 슬로우 쿼리
  • 디자인패턴
  • 스프링 검증
  • 알고리즘
  • 이펙티브 자바 item9

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

자바스크립트/모던 자바스크립트

모던 자바스크립트, 심볼 (Symbol)

2022. 12. 23. 22:56

Symbol 이란?

  • ES2015 에서 추가된 7번째 타입으로 원시 데이터 타입(primitive data type)이다.
    • 전까지는 Boolean, null, undefined, Number, String, Object 가 있었다.
  • 익명의 오브젝트 프로퍼티를 만드는데 이용된다.
    • 이름 충돌이 없는 유일한 객체 프로퍼티를 만든다.
    • 프로퍼티를 의도치 않은 노출로부터 보호한다.
  • 자바스크립트 빌트인 객체에 이미 많이 쓰이고 있다.
    • 이는 심볼을 이용해 빌트인 객체를 확장해서 쓰라는 의도도 있다.

Symbol 추가가 갖는 의의

왜 굳이 고유한 객체의 키값이 필요할까? 문자열로 하면 안되는 걸까?

  • 자바스크립트 언어 스펙을 정하는 사람들은 새로운 속성이나 메서드를 추가할 때 "다른 개발자들이 이미 쓰고있는 이름은 아닐까?" 하는 고민을 많이 했다.
  • 문자열 키는 잘못 사용하면 이미 있는 키에 값을 덮어씌울 수도 있다는 단점을 가지고 있다.
  • Symbol 을 이용하면, 다른 개발자들이 해당 키를 사용하는지 걱정하지 않고 마음껏 새로운 기능을 추가할 수 있다.
    • Symbol 은 Object.keys() 와 같은 메서드로 열거되지도 않기 때문에, 기존의 하위 호환성을 지키기 좋다.
  • Symbol 을 통해 규약을 만들고 활용할 수도 있다.
    • 일례로 Well-known Symbols 라는 것이 있다.
    • 이는 특별한 규약이 적용된 심볼들이라고 보면 된다.
      • Well-known Symbols 의 getter 메서드를 오버라이드하면, 규약에 따른 기존 기능을 변경할 수 있다.
        • ex) Symbol.toPrimitive 심볼 메서드를 오버라이드하면, 객체를 프리미티브 타입으로 변환할 때 어떠한 형태로 변할지를 오버라이드 할 수 있다.
        • ex) Symbol.toSpecies 심볼 메서드를 오버라이드하면, 빌트인 메서드의 결과로 반환되는 타입을 오버라이드 할 수 있다.

기본 사용 예제

var  myPrivateMethod  = Symbol();
this[myPrivateMethod] = function() {...};
  • 심볼로 작성한 키는 비 열거형이라 일반적인 방법으로 접근 불가능하며, 보통 myPrivateMethod 심볼을 통해서 접근한다.
  • Object.getOwnPropertySymbols() 이 반환하는 배열을 반복하여 접근하는 것도 가능하다.

심볼의 특징 1: 절대 동치가 되지 않는다.

var symbol1 = Symbol("S");
var symbol2 = Symbol("S");

console.log(symbol1 === symbol2); // false
  • 두 심볼은 동치가 되지 않는다.
    • Symbol() 에 인자로 들어가는 문자열은 심볼에 대한 설명을 위해 디버깅 용도로 들어가는 것이지 심볼의 아이덴티티를 결정하지는 않는다.
    • 인자로 똑같이 "S" 가 들어갔다고 해서 같은 심볼이 되지 않는다.
  • 이러한 이유로 Symbol 값을 키로 갖는 프로퍼티는 다른 어떠한 프로퍼티와도 충돌하지 않는다.
  • 심볼을 만든 뒤에 한번 참조를 놓치면 그 심볼은 영영 다시 가져올 수 없는 것이다.

심볼의 특징 2: Symbol 은 new 키워드로 생성이 불가능하다.

  • Symbol() 이 새로운 심볼을 생성하는 유일한 방법이다.
  • 혼동을 막기 위해 new Symbol() 등은 막아두었다.

심볼의 특징 4: 심볼은 정보 은닉을 위한 것이 아니다.

  • Symbol 을 키로 쓰는 프로퍼티는 Object.getOwnPropertySymbols() 메서드를 통해 가져올 수 있다.
    • 키로 사용되는 심볼을 배열 형태로 가져온다.
  • 속성에 대한 정보 은닉은 제공하지 않는다.
const mySymbol = Symbol("MySymbol");

const obj = {
  [mySymbol]: "It is my symbol.",
};

console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(MySymbol)]

심볼 테이블을 통해 심볼 만들기

  • 특정한 심볼을 꺼내쓰기 위해 전역 심볼 테이블이라는 것이 존재한다.
  • Symbol 은 .for() 와 .keyFor() 와 같은 메서드를 갖는다.
    • 이는 전역 심볼 테이블(혹은 레지스트리)과 런타임 환경 사이를 중재한다.
  • 전역 심볼 레지스트리(혹은 전역 심볼 테이블)는 자바스크립트 컴파일러의 인프라스트럭쳐에 의해 구축된다.
  • 심볼 레지스트리의 내용은 리플렉티브 메서드를 통하지 않고 접근이 불가능하다.

Symbol.for(): 전역 심볼 레지스트리에서 심볼 가져오기

const symbol_1 = Symbol.for("ABC"); // Symbol(ABC)
console.log(symbol_1 === Symbol.for("ABC")); // true;
  • 전역 심볼 레지스트리로부터 심볼 값을 반환한다.
  • 전역 심볼 레지스트리에서 가져온 심볼에는 키라는것이 존재하여, 동치인 심볼을 가져올 수도 있다.
    • 단순히 Symbol() 을 통해 생성된 심볼은 키가 없어 동치인 심볼을 한번 더 생성하는 것이 불가능하다.

Symbol.keyFor(): 심볼의 키 가져오기

const symbol1 = Symbol("S");
console.log(Symbol.keyFor(symbol1)); // undefined

const symbol2 = Symbol.for("ABC");
console.log(Symbol.keyFor(symbol2)); // 'ABC'
  • 심볼은 동치 판단을 위해 key 를 가질 수 있다.
  • Symbol() 생성자를 통해 만든 심볼은 key 가 없다.
  • 전역 심볼 레지스트리에서 가져오는 심볼은 key 가 있다.
  • Symbol.keyFor() 메서드는 심볼로부터 키(토큰 문자열)를 반환한다.
  • Symbol() 을 통해 생성된 심볼인 symbol1 은 위에서 말했듯 키가 없으므로 undefined 가 반환된다.
  • Symbol.for() 를 통해 생성된 심볼인 symbol2 는 위에서 말했듯 키가 있으므로 ABC 가 반환된다.

잘 알려진 심볼 (Well-Known Symbol)

  • Well-Known Symbol 이란, 자바스크립트 엔진에 상수로 존재하는 심볼이다.
  • 처음에도 설명했듯, 특정한 규약을 따르기 위한 목적으로 만들어진 심볼이다.
  • 어떤 오브젝트가 Symbol.iterator 를 키로 한 메서드를 가지고 있다면, 자바스크립트 엔진은 이 오브젝트가 이터레이션 프로토콜을 따른다고 본다는 식이다.

Symbol.iterator 심볼 이용해보기

Array.prototype[Symbol.iterator]; // ƒ values() { [native code] }
  • Array 빌트인 객체의 프로토타입 객체의 Symbol.iterator 에 접근하면, iterator 를 반환한다.
const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

console.log(arr instanceof Array); // true;
  • 반환된 iterator 를 이용해보았다.

Symbol.toStringTag 오버라이드 해보기

class Example1 {}
class Example2 {
  get [Symbol.toStringTag]() {
    return "Example2";
  }
}

const example1 = new Example1();
const example2 = new Example2();

console.log(example1.toString()); // [object Object]
console.log(example2.toString()); // [object Example2]
  • Symbol.toStringTag getter 를 오버라이드하면 이름처럼 toString() 메서드를 통해 나오는 값이 오버라이드된다.
  • 이렇게 오버라이드가 가능한 이유는 Object.prototype.toString() 메서드 구현이 Symbol.toStringTag 의 getter 반환 값을 이용하기 때문이다.
    • 자바스크립트 빌트인 객체는 이렇게 Well-known Symbol 규약을 잘 지키고 있기 때문에 개발자는 오버라이드하여 기능을 확장하기 좋다.

레퍼런스

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol
https://poiemaweb.com/es6-symbol#:~:text=%EC%8B%AC%EB%B3%BC(symbol)%EC%9D%80%20ES6%EC%97%90%EC%84%9C,%EB%A5%BC%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20%EC%9C%84%ED%95%B4%20%EC%82%AC%EC%9A%A9%ED%95%9C%EB%8B%A4.

반응형
저작자표시 비영리 (새창열림)

'자바스크립트 > 모던 자바스크립트' 카테고리의 다른 글

ES6 이후에 새롭게 정의된 Object 편의 정적 메서드들  (0) 2023.01.30
모던 자바스크립트, 메서드 정의 문법과 super, [[HomeObject]]  (0) 2023.01.25
모던 자바스크립트, 단축 속성 (shorthand properties)  (0) 2023.01.24
모던 자바스크립트, 계산된 속성 이름 (computed property name)  (0) 2023.01.24
모던 자바스크립트, 프로토타입 얻기 설정하기 (getPrototypeOf, setPrototypeOf)  (0) 2023.01.24
    '자바스크립트/모던 자바스크립트' 카테고리의 다른 글
    • 모던 자바스크립트, 메서드 정의 문법과 super, [[HomeObject]]
    • 모던 자바스크립트, 단축 속성 (shorthand properties)
    • 모던 자바스크립트, 계산된 속성 이름 (computed property name)
    • 모던 자바스크립트, 프로토타입 얻기 설정하기 (getPrototypeOf, setPrototypeOf)
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바