JS Symbol, 도대체?

원시 데이터 유형 중 Symbol 에 대해 이미 들어봤을 것입니다. 그러나 당신은 그것이 무엇인지 스스로에게 묻고 있습니다. 언제 유용합니까? 그들은 현재 언제 사용됩니까?
그렇다면 올바른 위치에 있습니다. 얼마전 제 경우였습니다 :)

그것은 무엇입니까?


Symbol는 ES6에 도입된 새로운 기본 데이터 유형입니다. 직접Symbol(optionalDescriptiveText) 사용하여 고유한 가치를 제공하거나 글로벌 Symbol 레지스트리를 통해 Symbol을 공유할 수 있습니다.
덕분에 다른 객체와 충돌하지 않도록 객체에 속성을 추가할 수 있습니다.

창조


고유한 가치



이전 부분에서 이미 망쳤습니다. Symbol(optionalDescriptiveText)를 사용하여 고유한 Symbol 값을 생성할 수 있습니다.

const myFirstSymbol = Symbol('This is my first symbol');


Watch out: the optional descriptive text is here just to add a description to the Symbol. It will not transform the string into a Symbol:



앞서 말했듯이 Symbol은 고유합니다.

// Will print false!!!
console.log(Symbol('Description') !== Symbol('Description'))


Warning: you cannot instantiate it as you may do with String, Boolean or Number:



// Will show you in the console something like
// Uncaught TypeError: Symbol is not a constructor
new Symbol('Trying to make an object');



공유 심볼



애플리케이션/라이브러리를 통해 공유할 Symbol를 만들 수도 있습니다.
다음과 같이 할 수 있습니다. Symbol.for(key) :

// Create a shared Symbol
const sharedSymbol = Symbol.for('Shared Symbol');

// You can assert that you can get this Symbol

// Will print true
console.log(sharedSymbol === Symbol.for('Shared Symbol'));


Note: You can create a shared Symbol with undefined / no key



// Will print true
console.log(Symbol.for() === Symbol.for(undefined));


Note: there is a keyFor method accessible from Symbol to retrieve the key of a shared Symbol:



const sharedSymbol = Symbol.for("Key of shared symbol");

// Will print: "Key of shared symbol"
console.log(Symbol.keyFor(sharedSymbol));


거짓말이 아닙니다. 어떤 상황에서 공유 심볼의 키를 검색하고 싶은지 모르겠습니다. 몇 가지 사용 사례를 알고 있다면 주저하지 말고 댓글에 남겨주세요 :)


자, 이제 Symbol 를 만드는 방법을 보았으므로 Symbol 가 있는 몇 가지 속성을 살펴보겠습니다.

속성



셀 수 없음



객체에 기호를 키로 추가하면 속성을 열거할 수 없습니다.

const person = {
  firstName: "Bob",
  lastName: "Sponge",
  [Symbol("secret")]: "I was created by a marine biologist",
};

// Will print
// Key: "firstName" and value: "Bob"
// Key: "lastName" and value: "Sponge"
Object.entries(person).forEach(([key, value]) =>
  console.log(`Key: "${key}" and value: "${value}"`)
);


iframe에서 동일한 값



예측할 수 없는 일이 발생합니다. 각 iframe 에는 자체 영역이 있으므로 Symbol 의 자체 인스턴스가 있습니다. 그러나 공유Symbol는 영역을 통해 동일합니다.

공유iframe를 선언하는 Symbol를 만들어 보겠습니다.

<iframe
  srcdoc="<script>
              var sharedSymbol = Symbol.for('Shared symbol');
              </script>"
></iframe>


이제 이것을 iframe 가져오고 contentWindow 속성을 통해 창을 가져옵니다.

const iframe = document.querySelector("iframe");
const iframeWindow = iframe.contentWindow;

// Will print false!
console.log(iframeWindow.Symbol === Symbol);

// But will print true!
console.log(
  iframeWindow.sharedSymbol === Symbol.for("Shared symbol")
);


Note: Thanks to it features added by well-known Symbols work through realms. For example for...of on iterable objects.

Note: var is accessible through the window object because it has global scope. Let's see my article for more explanations.



현재 사용법: 잘 알려진 기호



매일 사용하는 메소드를 구현하는 데 사용되는 잘 알려진Symbol s가 있습니다.

Note: These well-known Symbols are static properties of Symbol and are referenced with the notation @@name that corresponds to Symbol.name.



몇 가지를 보자:
  • Symbol.iterator : 이 기호는 for...of를 사용할 수 있도록 하는 객체의 기본 반복자를 정의합니다. 그러면 객체가 반복 가능합니다.

  • 예를 들어, 유형이 ArrayPerson가 있는 경우:

    type Person = {
      firstName: string;
      lastName: string;
    }
    


    그리고 이것을 반복할 때 Array 템플릿을 직접 얻고 싶습니다 ${firstName} ${lastName} . 코드는 다음과 같습니다.

    const persons = [
      { lastName: "Spears", firstName: "Britney" },
      {
        lastName: "Grande",
        firstName: "Ariana",
      },
      {
        lastName: "Timberlake",
        firstName: "Justin",
      },
    ];
    
    persons[Symbol.iterator] = function () {
      let index = 0;
      return {
        next: () => {
          const hasNext = this.length > index;
    
          if (hasNext) {
            const person = this[index++];
    
            return {
              done: false,
              value: `${person.firstName} ${person.lastName}`,
            };
          } else {
            return {
              done: true,
            };
          }
        },
      };
    };
    
    // This will print
    // Britney Spears
    // Ariana Grande
    // Justin Timberlake
    for (let person of persons) {
      console.log(person);
    }
    


    Note: It's possible to implement it with generators to make it "simpler". But not to lost people I decided to code it "manually".




  • Symbol.hasInstance : 이 기호는 클래스에 대한 instanceof 연산자의 구성을 관리합니다.

  • 예를 들어, 두 개의 클래스 BuildingHouse 가 있다고 가정해 보겠습니다.new House() instanceof Building가 true를 반환하기를 원합니다. 우리는 할 수있어:

    class Building {
      constructor() {
        this.type = "building";
      }
    
      static [Symbol.hasInstance](instance) {
        return (
          instance.type === "house" ||
          instance.type === "building"
        );
      }
    }
    
    class House {
      constructor() {
        this.type = "house";
      }
    
      static [Symbol.hasInstance](instance) {
        return instance.type === "house";
      }
    }
    
    // Will print true
    console.log(new House() instanceof Building);
    // Will print false
    console.log(new Building() instanceof House);
    


    Note: In real world, we would not do this but just:



    class Building {}
    
    class House extends Building {}
    



  • Symbol.split : 이 기호는 메서드로 사용할 수 있으며 Stringsplit 메서드에 의해 호출됩니다.

  • 예를 들어 구를 공백으로 분리하는 WordSplit 클래스를 정의할 수 있습니다.

    class WordSplit {
      [Symbol.split](string) {
        return string.split(" ");
      }
    }
    
    console.log(
      "A phrase that will be splitted".split(new WordSplit())
    );
    



  • Symbol.toStringTag : 기호를 사용하여 개체를 설명하는 데 사용할 문자열을 반환하는 개체의 속성을 정의할 수 있습니다. 이 메서드는 ObjecttoString 메서드에 의해 호출됩니다.

  • class Computer {
      constructor() {
        this[Symbol.toStringTag] = "Computer";
      }
    }
    
    // Will print [object Computer]
    console.log(new Computer().toString());
    


    Note: Otherwise it would print [object Object]




    결론


    Symbol가 무엇인지, 그 속성과 현재 사용되는 위치를 함께 볼 수 있습니다. Symbol 가 무엇이고 현재 일상 생활 기능에서 사용되는 위치가 이제 명확해지기를 바랍니다. 따라서 Symbol가 더 이상 유용하지 않다고 스스로에게 말하지 마십시오(만약 그렇다면) :)

    재미있는 사실, React는 Symbol 속성을 통해 요소 유형에 태그를 지정하기 위해 $$typeof : see code 을 사용합니다.


    주저하지 말고 댓글을 달고 더 보고 싶으시면 저를 팔로우하거나 내Website로 이동하세요. 🐼

    좋은 웹페이지 즐겨찾기