누가 Javascript 기호를 필요로 합니까?

표지 사진은 Alexander Fradellafra부터Pixabay
Symbols는 자바스크립트string, number, bigint, boolean and undefined에서 잘 알려지지 않은 원시 데이터 형식이다.그것들은 ES6 규범의 일부분으로 추가된 것이다. ES6 규범은 자바스크립트 언어의 큰 변화면으로 많은 새로운 특성을 포함하고 있다.

왜 우리는 부호가 필요합니까?


기호에는 다음과 같은 두 가지 주요 용례가 있습니다.
  • 객체에 다른 코드를 생성합니다(사용되는 기호를 참조하지 않음). 액세스하거나 덮어쓸 수 없는 숨겨진 속성입니다.대부분의 내장 함수와 라이브러리는 객체에 명시된 기호를 직접 변경하지 않으면 이 기호를 참조하지 않는 것이 관례입니다.
  • 객체의 기본 비헤이비어를 변경하는 데 사용되는 시스템 기호 - 예를 들어, Symbol.toPrimitive 객체를 기본으로 변환하는 동안 객체 비헤이비어를 정의하거나 Symbol.iterator 교체 중에 객체 비헤이비어를 설정하는 데 사용됩니다.
  • 기호 기반


    기호의 문법은 매우 간단하다.우리는 글을 써서 새 기호를 만들 수 있다.
    // mySymbol is a new created symbol
    let mySymbol = Symbol();
    console.log(mySymbol) // Symbol()
    
    Symbol() 함수에는 다음과 같은 설명 필드가 있습니다.
    // mySymbol is a new created symbol that now has a description
    let mySymbol = Symbol('decription of my symbol');
    console.log(mySymbol) // Symbol(decription of my symbol)
    
    설명 필드는 기호에 첨부되는 텍스트일 뿐입니다. 디버깅 목적으로 사용됩니다.
    symbol () 함수에서 되돌아오는 모든 기호는 유일합니다. 이것은 이 함수를 사용하여 만든 두 기호가 영원히 같지 않다는 것을 의미합니다.
    let firstSymbol = Symbol("sameDescription");
    let secondSymbol = Symbol("sameDescription");
    console.log(firstSymbol == secondSymbol); //false
    

    객체에 숨겨진 특성 생성하기


    이제 새로운 기호를 만드는 방법을 알게 되면, 그것을 사용하여 대상의 숨겨진 속성을 만드는 방법을 봅시다.

    우선, 우리는 왜 이렇게 해야 합니까?
    흔히 볼 수 있는 용례로서 나는 우리의 코드가 제3자에게 사용될 때 예를 들 수 있다.예를 들어 우리는 소스 라이브러리나 우리 조직의 다른 개발진이 사용할 라이브러리를 작성하고 있다.우리는 코드에 접근할 수 있도록 대상에 숨겨진 속성을 추가하기를 원할 수도 있지만, 다른 코드가 이 속성에 접근할 수 없다는 것을 보증하기를 원할 수도 있다.
    만약 우리가 문자열에 의해 성명된 일반적인 대상 속성을 사용한다면, 우리 라이브러리를 사용하는 개발자는 대상 키를 교체하거나 같은 이름의 속성을 만들고 덮어쓰면 의외로 이 점을 할 수 있다.
    기호는 여기서 우리를 돕는다.
    예를 들어 우리가 록 스타를 대표하는 물체가 있다고 가정해 보자.
    let rockStar = {
      name: "James Hetfield",
      band: "Metallica",
      role: "Voice & Rythm guitar"
    }
    
    현재, 우리는 숨겨진 속성을 추가하고 싶습니다. 이 속성은 내부 id를 표시합니다. 우리는 코드에서 이 id를 공개하고 내부 코드 밖에서 사용하지 않으려고 합니다.
    let idSymbol = Symbol('id symbol used in rockStar object');
    
    let rockStar = {
      name: "James Hetfield",
      band: "Metallica",
      role: "Voice & Rythm guitar"
      [idSymbol]: "this-id-property-is-set-by-symbol"
    }
    
    만약 우리가 지금 기호를 사용하여 속성 집합에 접근하거나 변경하거나 삭제하려고 한다면, 우리는 그것을 설명하는 기호를 인용해야 한다.그것이 없으면 우리는 이렇게 할 수 없다.
    또한 객체의 키를 교체할 때 속성 세트에 대한 참조는 기호를 사용하지 않습니다.
    console.log(Object.keys(rockStar)); // (3) ["name", "band", "role"]
    
    for ... in ... 순환도 우리의 기호를 무시합니다.
    for (key in rockStar) {
        console.log(key);
    }
    
    // output:
    // name
    // band
    // role
    
    

    글로벌 기호 레지스트리


    만약 어떤 경우, 우리는 기호로 정의된 속성에 접근할 수 있도록 기능을 추가하기를 원한다면, 어떻게 해야 합니까?만약 우리가 응용 프로그램의 서로 다른 모듈 사이에서 이러한 속성에 대한 접근을 공유해야 한다면 어떻게 해야 합니까?
    이것이 바로 전 세계 기호 등록 센터가 우리를 도와주는 곳이다.코드의 어느 곳에서든 접근할 수 있고, 특정한 키를 통해 기호를 설정하거나 얻을 수 있는 전역 수준의 사전으로 간주할 수 있다.Symbol.for는 전역 등록표에서 기호를 얻는 데 사용되는 문법이다.
    동일한 예를 들어 글로벌 레지스트리를 사용하여 다시 작성합니다.
    let idSymbol = Symbol.for('rockStarIdSymbol');
    
    let rockStar = {
      name: "James Hetfield",
      band: "Metallica",
      role: "Voice & Rythm guitar"
      [idSymbol]: "this-id-property-is-set-by-symbol"
    }
    
    let idSymbol = Symbol.for('rockStarIdSymbol'); 다음 작업을 수행합니다.
  • 전역 등록표에 rockStarIdSymbol와 같은 키와 관련된 기호가 있는지 확인하고 있으면 되돌려줍니다
  • 없는 경우 - 새 기호를 작성하여 레지스트리에 저장하고 반환합니다.
  • 즉, 코드의 다른 위치에서 재산에 액세스해야 하는 경우 다음을 수행할 수 있습니다.
    let newSymbol = Symbol.for('rockStarIdSymbol');
    console.log(rockStar[newSymbol]); // "this-id-property-is-set-by-symbol"
    
    따라서 특히 전역 레지스트리에서 같은 항목이 반환하는 두 개의 다른 기호는 동일합니다.
    let symbol1 = Symbol.for('rockStarIdSymbol');
    let symbol2 = Symbol.for('rockStarIdSymbol');
    console.log(symbol1 === symbol2); // true
    
    전역 등록표에서 어떤 키 기호와 관련이 있는지 Symbol.keyFor 함수를 사용하여 검사할 수 있는 방법도 있다.
    const symbolForRockstar = Symbol.for('rockStarIdSymbol')
    console.log(Symbol.keyFor(symbolForRockstar)); //rockStarIdSymbol
    
    Symbol.keyFor 전역 등록표를 검사하고 기호의 항목을 찾고 있습니다.기호가 레지스트리에 등록되지 않으면 - undefined 로 돌아갑니다.

    시스템 기호


    시스템 기호는 객체 비헤이비어를 사용자 정의하는 데 사용할 수 있는 기호입니다.시스템 기호의 전체 목록은 latest language specification 에서 확인할 수 있습니다.모든 시스템 기호는 몇 가지 규범을 제공하는데, 우리는 이 규범들을 덮어쓰고 사용자 정의할 수 있다.

    예를 들어 상용 기호 중의 하나인 용법-Symbol.iterator을 살펴보자. 이것은 우리로 하여금 iterator규범에 접근할 수 있게 한다.
    밴드를 나타내는 Javascript 클래스를 작성해야 한다고 가정해 보세요.
    그것은 밴드의 이름, 스타일, 그리고 밴드 멤버들의 명단이 있을 수 있다.
    class Band {
       constructor(name, style, members) {
         this.name = name;
         this.style = style;
         this.members = members;
       }
    }
    
    우리는 다음 내용을 작성하여 이 클래스의 새로운 실례를 만들 수 있다.
    const metallicaBand = new Band('Metallica', 'Heavy metal', 
    ['James', 'Lars', 'Kirk', 'Robert'];
    
    만약 우리가 우리 사용자가 여러 그룹을 훑어보는 것처럼 반복적인 실례를 가지고 구성원의 이름을 얻기를 원한다면, 어떻게 해야 합니까?이런 행위는 수조를 대상에 봉인하는 라이브러리에서 다시 사용된다.
    현재 - 만약에 우리가 for ... of 순환을 사용하여 대상을 교체하려고 한다면 - 우리는 오류를 얻게 될 것이다. 즉, Uncaught TypeError: "metallicaBand" is not iterable.이것은 우리의 클래스 정의가 어떻게 교체하는지에 대한 설명이 없기 때문이다.만약 우리가 정말로 교체를 사용하고 싶다면, 우리는 행위와 기호를 설정해야 한다.교체기는 우리가 반드시 사용해야 할 시스템 기호다.
    클래스 정의에 추가합니다.
    class Band {
       constructor(name, style, members) {
         this.name = name;
         this.style = style;
         this.members = members;
       }
    
      [Symbol.iterator]() { 
        return new BandIterator(this);
      }
    }
    
    class BandIterator{
      // iterator implementation
    }
    
    나는 교체기의 실제 실현을 깊이 있게 토론하지 않을 것이다. 이것은 다른 문장에 있어서 매우 좋은 주제이다.그러나 기호라면 우리가 알아야 할 용례다.거의 모든 본기 동작을 변경할 수 있습니다. 시스템 기호는javascript 클래스에서 이 점을 실현하는 방법입니다.

    또 뭐 있어요?


    1) 음, 기호로 설정된 대상의 기술적 속성은 100% 숨겨진 것이 아니다.방법Object.getOwnPropertySymbols(obj)이 대상에 설정된 모든 기호를 되돌려주고, 방법Reflect.ownKeys(obj)은 대상에 설정된 모든 속성을 표시합니다. 기호를 포함합니다.그러나 흔히 볼 수 있는 관례는 이러한 방법으로 열거, 교체, 대상에 대한 다른 일반적인 조작을 사용하지 않는 것이다.
    2) 코드에 열거 값을 나타내는 기호가 있는 것을 몇 번 보았습니다. 예를 들면:
    const ColorEnum = Object.freeze({
      RED: Symbol("RED"), 
      BLUE: Symbol("BLUE")
    });
    
    이런 방법이 얼마나 좋은지 확실하지 않다.기호를 정렬할 수 없고 문자열화하려고 시도할 때마다 객체에서 삭제됩니다.
    기호를 사용할 때 서열화를 조심해서 사용하십시오.전체적으로 말하자면 JSON.parse(JSON.stringify(...)) 를 사용하여 깊이 있게 복제하는 것을 피한다.이런 방법은 때때로 포착하기 어려운 오류를 초래하여 불면증을 초래할 수 있다!
    3) 얕은 객체 복제에 사용되는 함수 - Object.assign 기호 및 일반 문자열 속성을 복사합니다.이것은 듣기에 일종의 적절한 설계 행위인 것 같다.
    나는 이것이 완전한 화면을 얻기 위해 당신이 알아야 할 기호에 대한 모든 지식이라고 생각한다.내가 뭘 잊었나?

    네가 이 점을 해내서 매우 기쁘다!
    읽어주셔서 감사합니다. 평소와 같이 피드백에 감사드립니다.
    만약에 나처럼 자바스크립트 - 방문https://watcherapp.online/을 좋아한다면 - 내 프로젝트는 한 곳에 모든 자바스크립트 블로그 게시물이 있고 재미있는 것이 많다!

    좋은 웹페이지 즐겨찾기