Posts 모던 자바스크립트 #4.7. 심볼형
Post
Cancel

모던 자바스크립트 #4.7. 심볼형

모던 JavaScript 튜토리얼을 따라가면서 정리합니다.

4.7 심볼형

  • 객체 프로퍼티 키로 오직 문자형과 심볼형만 가능하다.

  • Symbol은 원시형 데이터로, 유일한 식별자(unique identifier)를 만드는 데 사용한다.

  • Symbol()을 호출하면 심볼을 만들 수 있다. 설명(이름)은 선택적으로 추가할 수 있다. 심볼 이름은 디버깅 시 유리하다.

  • 심볼은 유일성이 보장되는 자료형이기 때문에, 설명(이름)이 같더라도 값이 항상 다르다. 심볼 설명은 어떤 것에도 영향을 주지 않는 이름표 역할만을 한다.

  • 심볼형은 다른 자료형으로 암시적 형변환(자동 형변환)되지 않는다. 자바스크립트에서는 ‘언어 차원의 보호 장치(language guard)’를 마련해 심볼형이 다른 형으로 변환되지 않게 막아준다. 심볼을 반드시 출력해줘야 할 경우 toString()을 명시적으로 호출해주자. symbol.description 프로퍼티를 이용하면 설명만 보여주는 것도 가능하다.

  • 이름이 같을 때 값도 같길 원한다면 전역 레지스트리를 사용해야 한다. Symbol.for(key)key라는 이름을 가진 전역 심볼을 반환한다. key라는 이름의 전역 심볼이 없으면 새로운 전역 심볼을 만들어준다. key가 같다면 Symbol.for은 어디서 호출하든 상관없이 항상 같은 심볼을 반환해준다. 전역 심볼 레지스트리 안에 있는 심볼은 전역 심볼이라고 불린다.

    전역 심볼을 찾을 때 사용되는 Symbol.for(key)에 반대되는 Symbol.keyFor(sym)을 사용하면 이름을 얻을 수 있다. 전역 심볼이 아닌 인자가 넘어오면 Symbol.keyForundefined를 반환한다.

    1
    2
    3
    4
    5
    
    // 이름을 이용해 심볼을 찾음
    let sym = Symbol.for("name");
      
    // 심볼을 이용해 이름을 얻음
    alert( Symbol.keyFor(sym) ); // name
    

    전역 심볼이 아닌 모든 심볼은 description 프로퍼티가 있기 때문에 일반 심볼에서 이름을 얻고 싶다면 description 프로퍼티를 사용한다.

심볼의 주요 유스테이스

  • 객체의 ‘숨김(hidden)’ 프로퍼티

    숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없는 프로퍼티이다.

    외부 스크립트나 라이브러리에 ‘속한’ 객체에 새로운 프로퍼티를 추가해 주고 싶다면 심볼을 만들고, 이를 프로퍼티 키로 사용하면 된다.

    1
    2
    3
    4
    5
    6
    7
    
    let user = { // 서드파티 코드에서 가져온 객체
      name: "John"
    };
      
    let id = Symbol("id");
    user[id] = 1;
    alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있다.
    

    서드파티 코드에서 가지고 온 객체는 함수로 새로운 프로퍼티를 추가할 수 없는데, 심볼을 사용하면 서드파티 코드가 모르게 해당 객체에 식별자를 부여할 수 있기 때문이다.

    심볼은 유일성이 보장되므로 개발자가 만든 식별자와 제3의 스크립트에서 만든 식별자가 이름이 같더라도 충돌하지 않는다. 만약 심볼 대신 문자열을 사용해 식별자를 만들었다면 충돌이 발생할 가능성이 있다.

    1
    2
    
    let id = Symbol("id");
    user[id] = "제3 스크립트 id값"
    
    1
    2
    3
    4
    5
    6
    
    let user = { name: "John" };
    // 우리가 만든 문자열 식별자
    user.id = "스크립트 id 값";
    // 제3의 스크립트가 만든 식별자
    // 값이 덮어 쓰여서 위에서 만든 식별자는 무의미해진다.
    user.id = "제3 스크립트 id 값";
    

    이런 특징을 이용하면 원하는 것을 객체 안에 ‘은밀하게’ 숨길 수 있다. 외부 스크립트에선 우리가 숨긴 것을 절대 볼 수 없다.

  • 객체리터럴을 사용해 객체를 만든 경우, 대괄호를 사용해 심볼형 키를 만들어야 한다.

    1
    2
    3
    4
    5
    6
    
    let id = Symbol("id");
      
    let user = {
      name: "John",
      [id]: 123
    }
    
  • 심볼형 프로퍼티 숨기기(hiding symbolic property) 원칙: 키가 심볼인 프로퍼티는 for...in에서 배제된다. Object.keys(user)에서도 키가 심볼인 프로퍼티는 배제된다.

    이 원칙 덕분에 외부 스크립트나 라이브러리는 심볼형 키를 가진 프로퍼티에 접근하지 못한다.

  • Object.assgin키가 심볼인 프로퍼티를 배제하지 않고 객체 모든 프로퍼티를 복사한다.

  • 자바스크립트 내부에서 사용되는 시스템 심볼Symbol.*로 접근할 수 있다. 시스템 심볼을 이용하면 내장 메서드 등 객체의 기본 동작을 변경할 수 있다.

    • Symbol.hasInstance
    • Symbol.isConcatSpreadable
    • Symbol.iterator
    • Symbol.toPrimitive

심볼을 완전히 숨길 방법은 없다. 내장 메서드 Object.getOwnPropertySymbols(obj)를 사용하면 모든 심볼을 볼 수 있고, 메서드 Reflect.ownKeys(obj)는 심볼형 키를 포함한 객체의 모든 키를 반환해준다. 그런데 대부분의 라이브러리, 내장 함수 등은 이런 메서드를 사용하지 않는다.

This post is licensed under CC BY 4.0 by the author.

모던 자바스크립트 #4.6. 옵셔널 체이닝 '?.'

이것이 안드로이드다 with 코틀린 #1 코틀린 기본문법: 1. 코딩 준비하기

Loading comments from Disqus ...