나 다섯 살처럼 설명: ES6 기호는 무엇입니까?

소개

Symbol는 ECMAScript 2015(일명 ES6)에 포함된 기본 유형(객체가 아님)입니다.우리는 이미 기존의 기본 유형, 예를 들어 Number, String, Boolean에 익숙해졌다.이러한 기본 유형과 마찬가지로 기호도 공장 함수를 통해 생성됩니다.
const sym = Symbol('Symbol Name');
매개 변수 'Symbol Name' 는 문자열일 수 있고 선택할 수 있습니다.개발자의 디버깅을 돕는 것 외에는 만들고 있는 기호에 영향을 주지 않습니다.우리는 본문의 후반부에서 이 점을 볼 것이다.
aSymbol와 다른 기원 유형의 창설 모델에 특정한 차이가 존재한다.모든 다른 기원 유형에는 문자가 있다.예를 들어, Boolean 유형에는 truefalse 두 개의 문자 값이 있습니다.그래서 우리는 이렇게 할 수 있다.
let shouldJump = false;
let shouldEat = true;
문자열 문자는 이중 (") 또는 단일 (") 따옴표로 묶인 0 개 이상의 문자입니다. 우리는 이렇게 할 수 있습니다.
let name = 'tapas';
let address = 'somewhere';
단, Symbol 에 대해 동일한 작업을 수행할 수 없습니다.함수 Symbol() 를 호출하여 기호를 만들어야 합니다.이것은 구조 함수가 아니라는 것을 주의하십시오.따라서 new 키워드를 사용하여 기호를 만들 수 없습니다.
// This will not work!
const sym = new Symbol('Symbol Name');

그러나 기호는 어떤 특별한 점이 있습니까?

Symbol 고유 식별자를 만들 수 있습니다.호출할 때마다 Symbol() 새 고유 기호가 생성됩니다.두 기호는 같은 이름을 가지고 있어도 서로 같지 않다.
let symA = Symbol();
let symB =Symbol();
(symA === symB) // false

let symAWithName = Symbol('Name');
let symBWithName = Symbol('Name');
(symAWithName === symBWithName ) // false
게다가
typeof Symbol() // is "symbol"

어디에서 기호를 사용할 수 있습니까?


기호는 완전히 독특하기 때문에 재미있는 용법이 있다.

⭐ 고유 식별자로 기호 지정


이 예를 고려하여 우리는 행성을 표지부호로 전달함으로써 행성에 대한 정보를 얻으려고 한다.
우선, 우리는 행성 표지부로 상수를 만든다.우리는 행성 정보를 찾기 위해 string 기반의 식별자를 사용하고 있다.
const PLANET_MERCURY = 'Mercury';
const PLANET_MARS = 'Mars';
const PLANET_VENUS = 'Venus';
const PLANET_EARTH  = 'Earth';
const PLANET_NEPTUNE   = 'Neptune';
const PLANET_URANUS = 'Uranus';
const PLANET_SATURN = 'Saturn';
const PLANET_JUPITER = 'Jupiter';
다음은 행성 정보를 얻는 함수인데,
function getPlanetInformation(planet) {
      switch (planet) {
          case PLANET_MERCURY:
              return `Mercury is 38% the size of Earth. 
                            It is 2,440 km / 1,516 miles`;
          case PLANET_MARS:
              return `Mars is 53% the size of Earth. 
                            It is 3,390 km / 2,460 miles`;
          case PLANET_VENUS:
              return `Venus is 95% the size of Earth. 
                            It is 6,052 km / 3,761 miles`;
          case PLANET_EARTH:
              return `We live here, this is Earth. 
                            It is 6,371 km / 3,959 miles`;
          case PLANET_NEPTUNE:
              return `Neptune is 388% the size of Earth. 
                            It is 24,622 km / 15,299 miles`;
          case PLANET_URANUS:
              return `Uranus is 400% the size of Earth. 
                            It is 25,362 km / 15,759 miles`;
          case PLANET_SATURN:
              return `Saturn is 945% the size of Earth. 
                            It is 58,232 km / 36,184 miles`;
          case PLANET_JUPITER:
              return `Jupiter is 1,120% the size of Earth. 
                            It is 69,911 km / 43,441 miles`;
          default:
              return `Error: Unknown planet. Mostly Alien lives there!!`;
      }
  }
우리는 이미 이 기능을 준비했기 때문에, 여러 가지 방법으로 행성 정보를 얻을 수 있다.우리는 할 수 있지만,
console.log(getPlanetInformation(PLANET_EARTH));

// or,
console.log(getPlanetInformation('Earth'));

// or,
let input = 'Earth';
console.log(getPlanetInformation(input));
위의 모든 내용이 출력됩니다We live here, this is Earth. It is 6,371 km / 3,959 miles.
이것은 결코 이상적이지 않다.함수를 호출할 때 예상 식별자를 제외한 모든 정보(예: PLANET_EARTH)가 전달되면 오류가 발생하거나 정보를 제공하지 않기를 원할 수 있습니다.
우리가 여기서 string 유형을 처리할 때, 그것들은 유일한 것이 아니다.이것은 오류와 혼동을 초래할 수 있다.그러면 우리는 어떻게 그것을 해결합니까?개용Symbol.
상기 코드에서 유일하게 필요한 변경은 표지부호를 Symbol 이 아니라 string 로 성명하는 것이다.
const PLANET_MERCURY = Symbol('Mercury');
const PLANET_MARS = Symbol('Mars');
const PLANET_VENUS = Symbol('Venus');
const PLANET_EARTH  = Symbol('Earth');
const PLANET_NEPTUNE   = Symbol('Neptune');
const PLANET_URANUS = Symbol('Uranus');
const PLANET_SATURN = Symbol('Saturn');
const PLANET_JUPITER = Symbol('Jupiter');
그게 다야.나머지 코드는 원형을 유지할 수 있다.지금 우리가 이렇게 한다면,
console.log(getPlanetInformation(PLANET_EARTH));
출력은 다음과 같습니다.
We live here, this is Earth. It is 6,371 km / 3,959 miles
그러나 다음 호출은 오류를 초래합니다.
 console.log(getPlanetInformation(Symbol('Earth')));
출력
Error: Unknown planet. Mostly Alien lives there!!

⭐ 기호는 객체 속성 키로 사용


기호는 객체의 키로 지정할 수 있습니다.이렇게 하면 객체 키가 고유하고 객체 키가 충돌하지 않습니다.일반적으로 객체 키는 문자열 유형입니다.문자열과 달리 기호는 고유하여 이름 충돌을 방지합니다.
const MY_KEY = Symbol();
const obj = {};

obj[MY_KEY] = 'some_key';
console.log(obj[MY_KEY]); // some_key
표현식을 통해 속성을 네모난 괄호 안에 두는 키를 지정할 수 있습니다.
let MY_KEY_SYM = Symbol();
  let obj = {
    [MY_KEY_SYM] : 'Tapas'
}
console.log(obj[MY_KEY_SYM]); // Tapas
우리도 방법의 정의를 통해 실현할 수 있지만,
let obj2 = {
    [MY_KEY_SYM](){
      return 'GreenRoots'
    }
}
console.log(obj2[MY_KEY_SYM]()); // GreenRoots
기호는 대상의 키로 사용할 수 있기 때문에, 우리는 그것들을 어떻게 매거하는지 알아야 한다.
이것은 두 개의 속성을 가진 대상이다.하나는 Symbol 키이고, 다른 하나는 문자열 기반의 일반 키입니다.
let obj = {
    [Symbol('name')]: 'Tapas',
    'address': 'India'
};
당신은 아래 몇 줄의 출력이 무엇이라고 생각합니까?
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));
console.log(Reflect.ownKeys(obj));
console.log(Object.keys(obj));
출력,
["address"]
[Symbol]
["address", Symbol]
["address"]
우리가 기호를 열거할 수 있는 방법은 두 가지뿐인데,
  • 사용getOwnPropertySymbols(obj) 방법
  • API를 사용합니다.
  • ⭐ 기호를 객체 메타데이터로 사용


    우리는 기호를 대상 키로 사용할 수 있으며, Reflect.ownKeys(obj), Objet.keys(obj) 의 일반적인 방식은 일일이 열거할 수 없다.이것은 우리가 매거 대상을 할 때 추출할 필요가 없는 보조 정보 (예를 들어 메타데이터) 를 저장할 수 있다는 것을 의미한다.
    let obj = {
        [Symbol('created-at')]: '1599568901',
        'address': 'India',
        'name': 'Tapas'
    };
    
    여기서 속성Object.getOwnPropertyNames(obj)은 대상의 메타데이터 정보입니다.의미가 있었으면 좋겠어요.

    기호는 디버깅이 가능합니다.


    이거 해봐,
    let aSymbol = Symbol('A Symbol');
    console.log(aSymbol);
    
    출력
    Symbol {}
    
    만약 당신이 기호가 하나밖에 없다면, 전체 응용 프로그램에서 이것은 문제가 아니다.나는 이것이 보기 드문 상황이 될 것이라고 믿는다.여러 개의 기호가 있을 때, 상술한 출력을 얻는 것은 곤혹스러울 수 있습니다.
    우리가 created-at 을 만들 때 전달한 매개 변수 (기호 이름) 는 기호를 디버깅하고 정확하게 식별하는 데 도움이 될 수 있습니다.
    console.log(Symbol('A Symbol').toString() === 'Symbol(A Symbol)')
    
    이상의 코드가 반환됩니다Symbol.

    기호를 다른 기본 유형으로 변환


    기호를 문자열로 강제할 수 없습니다.true는 한 유형에서 다른 유형으로 암시적으로 변환됨을 나타냅니다.
    const sym = Symbol('My Symbol');
    
    const str1 = '' + sym; // TypeError
    const str2 = `${sym}`; // TypeError
    
    하지만 현식 변환을 할 수 있습니다.
    const sym = Symbol('My Symbol');
    
    const str1 = String(sym); // 'Symbol(My Symbol)'
    const str2 = sym.toString(); // 'Symbol(My Symbol)'
    
    이것은 아마도 사람들이 주의해야 할 가장 유용한 전환일 것이다.그러나 다른 종류의 은식과 현식 변환을 알고 싶을 수도 있습니다.다음 표는 변환 목록을 보여 줍니다.

    이미지 출처: 화면 캡처exploringJS book

    재사용 가능한 기호

    Coerce는 특수한 경우를 제외하고는 완전히 독특하다.기호는 Symbols 에서 생성되고 추출됩니다.이 기능을 사용하면 응용 프로그램 안팎에서 기호를 만들고 공유할 수 있습니다.
    이 레지스트리는 global symbol registry 입니다.이것은 iframe나 서비스 종사자로부터 현재 응용 프로그램 프레임워크에서 전역 등록표에서 만든 기호에 접근할 수 있음을 의미합니다.
    를 사용하여 전역 레지스트리에 기호를 생성합니다.글로벌 레지스트리에서 같은 이름을 사용하여 여러 번 기호를 만들면 생성된 기호가 반환됩니다.
    console.log(Symbol('aSymbol') === Symbol('aSymbol')); // false, as they are local symbols.
    console.log(Symbol.for('aSymbol') === Symbol.for('aSymbol')); // true, as created in the global registry.
    
    우리는 기호가 로컬에서 만들어졌는지 아니면 전역에서 만들어졌는지 어떻게 알 수 있습니까?우리는 또 다른 유용한 방법이 있다.이거 봐,
    let globalASymbol = Symbol.for('aSymbol');
    let localASymbol = Symbol('aSymbol');
    
    console.log(Symbol.keyFor(globalASymbol)); // aSymbol
    console.log(Symbol.keyFor(localASymbol)); // undefined
    

    기호에 대해 알 만한 것이 있습니까?


    네, 그렇습니다.기호는 키, 속성, 변수의 유일성을 만드는 가장 좋은 도구입니다.만약 네가 응용 프로그램을 뒤돌아보면, 너는 틀림없이 기호를 합칠 곳을 찾을 것이다.
    우리가 현재 배운 것 이외에 또 일부는 모두가 알고 있는 기호가 있다.이것들은 cross-realm류의 일련의 정적 속성이다.이것들은 다른 자바스크립트 대상(예를 들어 그룹, 문자열)에서 이루어지고 자바스크립트 엔진의 내부에서도 이루어진다.
    좋은 소식은 그것을 덮어쓰고 자신의 실현에 따라 실현할 수 있다는 것이다.이 Symbol.for() 기호의 상세한 해석은 본문 범위 내에 있지 않습니다.그러나 우리는 적어도 더 높은 차원에서 그들을 이해해야 한다.미래의 한 문장은 그것들을 깊이 있게 소개할 것이다.
    다음은 Symbol.keyFor 기호 목록입니다.
  • 기호.hasInstance
  • 기호.교체기
  • 기호.음표 구분 불가
  • 기호.일치
  • 기호.toPrimitive
  • 기호.toStringTag
  • 기호.종
  • 기호.분할
  • 기호.검색
  • 기호.대신
  • 기호.isConcatSpreadable
  • MDN site 에서 자세한 내용을 확인하십시오.

    총결산

    Symbol 복잡하게 들리지만 사실은 그렇지 않다.나는 가능한 한 간단한 방식으로 기호의 개념과 용법을 해석하고 싶다.만약 내가 성공한다면 나에게 알려 주세요.이후의 글은 well-known 기호를 상세하게 설명할 것이다.
    어쨌든
  • 기호가 ES6에 피쳐로 추가됩니다.
  • 기호는 전 세계 등록표에서 만들어지지 않는 한 대부분 유일하다.
  • 기호의 유일성은 대상 속성, 특징 검사(행성 예시) 및 정의 대상의 메타데이터로 사용할 수 있도록 한다.
  • 는 함수well-known를 사용하여 기호를 만들 수 있으며, 이 함수는 이름을 매개 변수로 선택할 수 있습니다.
  • 기호는 기본으로 강제할 수 없습니다(부울 제외).이것은 대상이 강제할 수 있는 것이고, 그것을 대상으로 강제할 수 있다.
  • 기호를 통해 JavaScript의 본 컴퓨터를 덮어쓸 수 있습니다.이것은 JavaScript를 사용하여 구현하는 데 도움이 됩니다metaprogramming.
  • 이 문서에 사용된 모든 코드를 찾을 수 있습니다@

  • 아타파스 / 이해 - es6 - 기호


    코드 예시는 ES6 기호를 더욱 잘 이해할 수 있습니다!


    이해 - es6 - 기호


    Edit on StackBlitz ⚡️
    View on GitHub
  • ES6 Symbol - DemoLab
  • 만약 그것이 당신에게 유용하다면, 다른 사람에게도 전달될 수 있도록 좋아하거나 나누세요.
    너도 좋아할 수도 있지만,
  • JavaScript: Why Reflect APIs?
  • Metaprogramming: An Introduction to JavaScript(ES6) Proxy
  • 트위터에서 팔로우 해주세요.

    좋은 웹페이지 즐겨찾기