반응형

 내용은 이웅모 님의 "모던 자바스크립트 DeepDive" 책을 보고 정리한 내용입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다.

 

심벌(Symbol)이란?

  • 심벌(Symbol)은 원시 데이터 타입 중 하나로, ES6에서 도입된 7번째 데이터 타입이다.
  • 유일하고 변경 불가능한 값을 나타내는 특별한 데이터 형식이다.
  • 주로 객체의 프로퍼티 키로 사용되며, 이러한 사용 시에는 다른 프로퍼티 키와 충돌하지 않는 고유한 식별자를 생성할 수 있다.
  • 심벌 값도 객체처럼 접근하면 암묵적으로 래퍼 객체를 생성한다.
  • 심벌 값은 암묵적으로 숫자나 문자타입으로 변환되지 않지만 boolean 타입으로는 변환된다.

예시)

// 심벌 생성
const symbol1 = Symbol();
// 심벌값은 외부 노출이 안돼서 확인할 수 없다.
console.log(symbol1); // 출력 : Symbol()

const symbol2 =  new Symbol(); // TypeError: Symbol is not a constructor

 

예시) 설명이 같은 심벌 비교

// 심벌 생성
const symbol1 = Symbol('description');
const symbol2 = Symbol('description'); // 설명 문자열을 포함한 심벌

// 심벌에 대한 설명이 같아도 심벌은 유일성을 가지고 있기에 서로 다르다
console.log(symbol1 === symbol2); // 출력 : false

 

예시) 심벌 값을 객체처럼 접근

// 심벌을 객체처럼 접근하면 래퍼 객체가 생성된다.
const symbol = Symbol('description');

const symbolWrapper = Object(symbol);

// 래퍼 객체의 프로퍼티에 접근할 수 있다.
console.log(symbolWrapper.description); // 출력 : description
console.log(symbolWrapper.toString()); // 출력 : Symbol(description)
console.log(symbolWrapper.valueOf() === symbol); // 출력 : true

// 래퍼 객체와 실제 심벌 값은 동등하지만 동일하지 않다.
console.log(symbolWrapper === symbol); // 출력 : false

 

예시) 심벌의 암묵적 타입 변환

const symbol = Symbol('description');

console.log(!!symbol); // 출력 : true
// console.log(symbol + ' '); // TypeError: Cannot convert a Symbol value to a string
// console.log(+ symbol); // TypeError: Cannot convert a Symbol value to a number

 

Symbol.for 메서드

  • Symbol.for 메서드는 주어진 설명(description)을 가지는 심벌을 생성하거나 이미 생성된 경우 해당 심벌을 반환한다.
  • 설명과 일치한 십벌값이 없으면 새로운 심벌 값을 생성하여 전역 심벌 레지스트리레 저장 후 , 저장된 십벌 값을 반환한다.
  • 애플리케이션 전역에서 중복되지 않는 유일무이한 상수인 심벌값을 단 하나만 생성하여 전역에서 공유할 수 있다.

예시)

const symbol1 = Symbol('description');
const symbol2 = Symbol.for('description');
const symbol3 = Symbol.for('description');

// Symbol 함수로 생성한 값과 for 메서드로 생성한 값은 다르다.
console.log(symbol1 === symbol2); // 출력 : false

// for 메서드 사용시 설명이 유일한 심벌값 생성
console.log(symbol2 === symbol3); // 출력 : true

 

Symbol.keyFor 메서드

  • 전역 레지스트리에 등록된 심벌을 찾고 해당 심벌의 설명을 반환한다.
  • 전역 레지스트리에 등록되지 않은 심벌을 전달하면 undefined를 반환한다.

예시)

const symbol1 = Symbol('description');
const symbol2 = Symbol.for('description');

// Symbol 함수로 생성한 값은 undefined 출력
console.log(Symbol.keyFor(symbol1)); // 출력 : undefined

// for 메서드로 생성한 값은 해당 설명을 출력
console.log(Symbol.keyFor(symbol2)); // 출력 : description

 

심벌과 상수

  • 상수의 값을 심벌로 생성하여 유일무이한 값을 사용할 수 있다.

예시)

// 객체 생성 및 프로퍼티 키로 사용
// 객체의 변경을 방지하려면 Object.freeze 메서드로 객체의 변경을 방지한다.
const Member = Object.freeze({ 
  NAME : Symbol('name'),
  ID : Symbol('id'),
  PW : Symbol('pw')
});

const member = Member.NAME;

console.log(member === Member.NAME); // 출력 : true

 

심벌과 프로퍼티 키

  • 심벌 값으로 프로퍼티 키를 만들면 다른 프로퍼키 키와 중복되지 않는 유일한 프로퍼티를 만들 수 있다.
  • 추후에 추가될 어떤 프로퍼티와도 중복되지 않는다.
  • 심벌 값을 프로퍼티키로 가지면 for ... in 문이나 Object.getOwnPropertyNames 메서드로 찾을 수 없어 외부에 노출할 필요가 없는 프로퍼티를 은닉할 수 있다.
  • Object.getOwnPropertySymbols 메서드를 사용하면 심벌 값을 키로 사용한 프로퍼티를 찾을 수 있다.

예시)

// 객체 생성 및 프로퍼티 키로 사용
const Member = { 
  [Symbol.for('name')] : '이름',
  [Symbol.for('id')] : '아이디',
  [Symbol.for('pw')] : '비밀번호'
};

console.log(Member[Symbol.for('name')]); // 출력 : 이름

for(const key in Member){
    console.log(key); // 아무것도 출력되지 않음
}

// getOwnPropertySymbols 메서드를 사용하면 심벌 프로퍼티 키를 배열로 반환한다.
console.log(Object.getOwnPropertySymbols(Member));

// 첫번째 심벌 프로퍼티키를 찾는다.
const sysmbolKey = Object.getOwnPropertySymbols(Member)[0];
console.log(Member[sysmbolKey]); // 이름
반응형

+ Recent posts