Symbol

Siwoo Pak·2021년 7월 7일
0

Javascript

목록 보기
16/34

1. Symbol

  • 값으로 익명의 객체 속성을 만들 수 있는 primitive data type.
  • 심볼 데이터 형식의 인스턴스를 생성하는 클래스와 유사한 심볼 함수

2. 데이터 형식

  • 심볼 데이터는 클래스나 객체 타입의 내부에서만 접근할 수 있도록 전용 객체의 속성의 키로 사용됨.
  • 심볼 형식으로 된 키는 js의 다양한 내장 객체 안에 존재함.
  • 사용자 지정 클래스 역시 이런한 방식으로 전용 멤버를 만들 수 있음
  • 고도로 특화된 용도로 쓰이기에 범용성은 떨어짐
  • 심볼의 인스턴스에 L값을 할당할 수 있고, 식별자로 이용할 수 있음. 하지만 이게 다임!
  • 심볼값이라고도 함.

3. Symbol()

  • js 런타임 환경 내에서 심볼값을 Symbol()를 호출하여 생성가능
  • 이 함수는 동적으로 익명의 고유한 값을 만들어 냄.
  • 심볼은 객체속성으로 사용될 수 있음.
var myPrivateMethod = Symbol(); //myPrivateMethod가 심볼값
this[myPrivateMethod] = function() {...};
  • 심볼값은 익명인 속성에 할당할때 식별자로 사용되며, 비열거형.
  • 자신이 가리키는 속성인 비열거형이기 때문에 for in 을 사용할수 없음
  • 그 속성이 익명이기 때문에 Object.getOwnPropertyNames()가 반환화는 배열에 들어갈수도 없음
  • 해당 속성은 그 속성을 만든 원래 심볼값을 이용하거나
  • Object.getOwnPropertySymbols()가 반환하는 배열을 반복함으로써 접근가능
  • 심볼함수는 new 생성자를 통해서 만들 수는 없다.
  • 심볼함수는 전역 심볼 테이블에 접근가능한 정적메서드와 공용으로 사용되는 객체를 가리키는 특정심볼의 주소값을 가지는 정적속석을 가짐.
  • 정적메서드: Symbol.for(), Symbol.keyFor()
    • 이 메서드들은 전역심볼 테이블(또는 레지스티리)와 런타임 환경을 중재.
    • 심볼 레지스트리 대부분 js의 컴파일러에 의해 구축되며, 심볼 레지스트리는의 컨텐츠는 이런한 리플렉티브 메서드를 통하지 않고선 접근할수 없음.
    • Symbol.for("tokenString")은 레지스트리부터 심볼값을 반환
    • Symbol.keyFor(symbolValue)는 레지스트리부터 토큰 문자열 반환
      Symbol.keyFor(Symbol.for("tokenString"));
      /// "tokenString" 출력

4. Symbol Class

  • 익명에 이름을 부여하는 몇 가지 정적인 속성을 가지고 있음.

  • 특정 내장 객체에 존재하는 몇개의 선택된 메서드 속성을 가리키는 심볼

  • Symbol.iterator, Symbol.search

    • Symbol.iterator
      • 객체에 대응하는 기본 이터레이터를 지정.
      • for ..of와 같이 사용됨.
    • Symbol.serach
      • 잘 알려진 심볼메서드로 정규식과 일치하는 문자열 내에서 인덱스를 반환함.
  • 심볼함수와 이 함수가 생성하는 심볼값은 프로그래머가 사용자 지정 클래스를 설계할 때 유용함.

  • 심볼값은 사용자 지정 클래스가 전용 멤버를 만들고 바로 그 클래스와 관련된 심볼 레지스트리를 유지 관린하는 방법을 제공

  • 사용자 지정 클래스는 심볼값을 이용하여 의도하지 않는 노출로부터 보호할 수 있는 "자신만의" 속성을 만들 수 있음.

  • 클래스 정의 내에서 동적으로 생성된 심볼값은 그 클래스 정의 내에서만 사용할 수 있는 스코프변수에 저장됨.

  • 토큰 문자열은 없지만, 그 스코프 변수는 토큰과 동일한 역할을 함.

Symbol("foo") !== Symbol("foo") //true
// Symbol() 익명의 고유한 값을 가짐
const foo = Symbol();
const bar = Symbol();
typeof foo === "symbol"; //true
typeof bar === "symbol"; //true

let obj = {};
obj[foo] = "foo"; //Symbol함수를 객체의 속성으로 씀
obj[bar] = "bar";
JSON.stringify(obj); //{}
Object.keys(obj); //[]
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [Symbol(),Symbol()] 
// 심볼함수를 속성으로 썼을때는 getOwnPropertySymbols()로만 접근가능

참고

1. L-Value와 R-Value

  • 공간(장소)를 의미함
  • R-Value는 읽어 들이는 것을 의미.
  • L-Value의 경우 데이터가 저장된 메모리 영역을 추적할 수 있는 값을 말하며, a=123에서 a라는 변수명은 os가 메모리에 123이라는 값을 보관하기 위한 메모리 주소의 별칭이므로 a 라는 변수를 통해 123이라는 값이 저장된 메모리 주소를 추적이 가능하므로 a는 L-Value
  • R-Value, 123의 경우 메모리 주소에 값을 넣기 위한 임시 데이터이므로 이는 cpu의 레지스터를 통해 메모리에 직접 기록되게 됨. 따라서 123값만으로 메모리를 주소를 추적할수 없으므로 R-Value
const foo = function() {
  console.log(this.name);
}
var name ='ad';
let a ={name:'vv'}, b={name:'ff'};
a.foo = foo;
b.foo = foo;
(a.foo)(); // 'vv'
(b.foo)(); // 'ff'
(a.foo = b.foo)(); // 'ad'
//(a.foo=b.foo)는 R-Value로 취급되어 foo 함수 객체의 데이터 그 자레를 의미하게 되며 이를 즉시 실행하므로 객체추적을 하지못해 전역변수 name의 값인 'ad'를 출력
(a.foo = b.foo) = foo;
//Invalid left-hand side in assignment 라는 오류가 발생한 것을 알수 있으며 이는 L-Value 가 아니므로 대입연산이 수행되지 않아 실패된다는 의미로 해석이 가능

2. Symbol 관련해서 참고할만한 자료

profile
'하루를 참고 인내하면 열흘을 벌 수 있고 사흘을 참고 견디면 30일을, 30일을 견디면 3년을 벌 수 있다.'

0개의 댓글