[JS] Symbol

say_ye·2022년 6월 2일
4

JavaScript

목록 보기
10/18
post-thumbnail

Symbol이란?

다른 값과 중복되지 않고 변경 불가능한 원시 타입의 값

문법

Symbol([description])

  • [description] : 선택적 문자열. 디버깅에 사용할 수 있는 심볼에 대한 설명일 뿐 심볼 자체에 접근하는 용도로는 사용할 수 없습니다.

특징

  • ES6에서 도입된 7번째 데이터 타입입니다.
  • 반드시 Symbol() 함수를 호출하여 생성합니다.
    const mySymbol = Symbol();
  • 객체의 프로퍼티 키로 사용될 수 있는 타입으로, 주로 이름의 충돌 위험이 없는 유일한 프로퍼티 키를 만들기 위해 사용합니다.
    Symbol("foo") === Symbol("foo"); // false
  • 생성된 심벌 값은 외부로 노출되지 않아 확인할 수 없습니다.
    const mySymbol = Symbol();
    console.log(mySymbol) // Symbol()
  • 생성자 함수로 객체를 생성하는 문법은 지원하지 않습니다.
    const mySymbol = new Symbol(); // <- 이게 될거같은데 안됩니다요.
  • 객체처럼 접근하면 암묵적으로 래퍼 객체를 생성합니다.
    래퍼 객체가 뭐냐면.. Symbol은 원시타입이니까 생성된 mySymbol은 객체가 아니잖아요?
    하지만 객체마냥 자연스럽게 프로퍼티, 메서드에 접근할 수 있기도 합니다. 이런식으로 원시타입의 프로퍼티에 접근할 때 원시값을 감싸며 생성되는 임시 객체를 래퍼 객체라고 합니다.
    const mySymbol = Symbol('ㅇㅅㅇ');
    console.log(mySymbol.description) // 'ㅇㅅㅇ'
    console.log(mySymbol.toString()) // 'Symbol(ㅇㅅㅇ)'
  • 암묵적으로 문자열이나 숫자 타입으로 변환되지 않으며 불리언으로는 변환 가능합니다.
    const mySymbol = Symbol();
    console.log(mySymbol + ''); // typeError
    console.log(+mySymbol); // typeError
    console.log(!!mySymbol); // true

메서드

  • Symbol.for(key)
    전역 심벌 레지스트리에서 key와 일치하는 심벌 값을 검색하여 해당 key로 저장된 심벌 값이 없으면 심벌 값 생성, 심벌 값이 있으면 해당 심벌 값을 반환합니다.
    이를 이용하여 심벌 값을 공유할 수 있습니다.
    참고로 Symbol() 로 생성된 심벌 값은 전역 심벌 레지스트리에 등록되지 않습니다.
    const s1 = Symbol('a')
    const s2 = Symbol.for('a')
    const s3 = Symbol.for('a')
    s1 === s2 // false
    s2 === s3 // true
    s1.description // 'a'
    s2.description // 'a'
  • Symbol.keyFor(key)
    전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출할 수 있습니다.
    const s1 = Symbol.for('mySymbol')
    Symbol.keyFor(s1) // mySymbol

사용 예시

  • 유일무이한 상수를 정의
    const Direction = {
    	UP: Symbol('up'),
    	DOWN: Symbol('down'),
    	LEFT: Symbol('left'),
    	RIGHT: Symbol('right')
    }
    Object.freeze() 랑 같이 쓰면 enum 처럼 쓰는것도 가능합니다.
    const Direction = Object.freeze({
    	UP: Symbol('up'),
    	DOWN: Symbol('down'),
    	LEFT: Symbol('left'),
    	RIGHT: Symbol('right')
    })
  • 객체의 프로퍼티키로 사용
    const obj = {
    	[Symbol.for('mySymbol')]: 1
    }
    obj[Symbol.for('mySymbol')];
    심벌값으로 프로퍼티 키를 만들면 ?
    • 다른 프로퍼티 키와 절대 충돌하지 않습니다.(((중요)))
    • for ... in 문, Object.key, Object.getOwnPropertyNames 로 찾을 수 없습니다.
    • 대신 Object.getOwnPropertySymbols로 찾을 수 있습니다.
  • 빌트인 객체에 메서드 추가
    Array.prototype[Symbol.for('decription')] = function () { ... }
    이렇게 추가하면 다른 프로퍼티 키와 겹칠까봐 걱정 안해도 됩니다.

빌트인 심벌 값

console.dir(Symbol) 을 찍어보면 빌트인된 다양한 심벌값을 확인할 수 있습니다.
이 중에 유명한 심벌값이 있다면 Symbol.iterator가 아닐까 싶은데요..?
mdn 문서에서 이터러블 프로토콜 용어 설명에서
Symbol.iterator를 프로퍼티로 가지면서 이터레이터를 반환한다 라는 표현을 이제는 이해할 수가 있어졌습니다~
이터레이터는 뭐냐고요? 그건 다음 포스팅에서 작성해보도록 하겠습니다


참고 링크
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol

profile
우당탕탕 삽질 기록

0개의 댓글