JavaScript 원본 데이터 유형 Symbol 자세히 보기

소개


symbol 변수를 만드는 가장 간단한 방법은 Symbol() 함수입니다.sysmbol 변수는 다음과 같은 두 가지 특징이 있습니다.
1. 개체 속성 이름으로 사용할 수 있습니다.문자열과symbol 형식만 대상 속성 이름으로 사용할 수 있습니다.
2. 두 symbol의 값이 같지 않다.

const symbol1 = Symbol();
const symbol2 = Symbol();

symbol1 === symbol2; // false

const obj = {};
obj[symbol1] = 'Hello';
obj[symbol2] = 'World';

obj[symbol1]; // 'Hello'
obj[symbol2]; // 'World'
Symbol () 을 호출하여 객체처럼 보이게 하지만, 실제로symbol은 JavaScript 원본 데이터 형식입니다.Symbol을 구조 함수로 사용하면 new로 오류를 보고할 수 있습니다.

const symbol1 = Symbol();

typeof symbol1; // 'symbol'
symbol1 instanceof Object; // false

// Throws "TypeError: Symbol is not a constructor"
new Symbol();

설명 정보


Symbol () 함수는 문자열 description이라는 매개변수만 있습니다.이 문자열 매개 변수의 유일한 역할은 보조 디버깅, 즉 toString () 값입니다.그러나 같은 description을 가진symbol 두 개도 같지 않다는 것을 주의하십시오.

const symbol1 = Symbol('my symbol');
const symbol2 = Symbol('my symbol');

symbol1 === symbol2; // false
console.log(symbol1); // 'Symbol(my symbol)'
전역적인symbol 등록 센터가 있습니다. Symbol을 사용하십시오.for () 에서 만든symbol은 이 등록 센터에 추가되고 description을 인덱스 키로 사용합니다.즉, 당신이 Symbol을 사용한다면.for () 같은 description을 가진symbol 두 개를 만듭니다. 같은 것입니다.

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

symbol1 === symbol2; // true
console.log(symbol1); // 'Symbol(test)'
통상적으로, 당신이 아주 좋은 이유를 가지고 있지 않으면, 전역 등록 센터를 사용해서는 안 된다. 왜냐하면 이것은 명명 충돌을 초래하기 때문이다.

이름 충돌


JavaScript에는 ES6의 Symbol이 내장되어 있습니다.iterator.Symbol이 있습니다.iterator 함수의 대상은 교체 가능한 대상이라고 합니다. 즉, 대상에서for/of 순환을 사용할 수 있습니다.

const fibonacci = {
  [Symbol.iterator]: function*() {
    let a = 1;
    let b = 1;
    let temp;

    yield b;

    while (true) {
      temp = a;
      a = a + b;
      b = temp;
      yield b;
    }
  }
};

// Prints every Fibonacci number less than 100
for (const x of fibonacci) {
  if (x >= 100) {
    break;
  }
  console.log(x);
}
왜 여기 심볼을 써요?문자열 대신iterator?Symbol을 사용하지 않는다고 가정해 보세요.iterator, 교체 가능한 대상은 문자열 속성 이름'iterator'가 필요합니다. 아래의 교체 가능한 대상의 클래스와 같습니다.

class MyClass {
  constructor(obj) {
    Object.assign(this, obj);
  }

  iterator() {
    const keys = Object.keys(this);
    let i = 0;
    return (function*() {
      if (i >= keys.length) {
        return;
      }
      yield keys[i++];
    })();
  }
}
MyClass 인스턴스는 객체 위의 속성을 반복할 수 있는 객체입니다.그러나 위의 클래스는 잠재적인 결함이 있습니다. 만약에 어떤 악성 사용자가 MyClass 구조 함수에iterator 속성을 가진 대상을 전달했다고 가정합니다.

const obj = new MyClass({ iterator: 'not a function' });
이렇게 해서 obj에서 for/of를 사용하면 JavaScript에서 TypeError: obj is not iterable 이상을 던집니다.들어오는 대상의iterator 함수가 클래스의iterator 속성을 덮어쓰는 것을 알 수 있습니다.이것은 원형 오염과 유사한 안전 문제입니다. 무뇌 복제 사용자 데이터는 일부 특수한 속성, 예를 들어 __proto__constructor와 문제를 가져옵니다.
이곳의 핵심은symbol이 대상의 내부 데이터와 사용자 데이터로 하여금 강물을 침범하지 않게 하는 데 있다.sysmbol은 JSON에 표시할 수 없기 때문에 Express API에 부적합한 Symbol을 전송할 염려가 없습니다.iterator 속성의 데이터입니다.또한 내장 함수와 사용자 데이터를 혼합한 대상, 예를 들어 Mongose 모델은 사용자 데이터가 내장 속성과 충돌하지 않도록symbol로 확보할 수 있다.

개인 속성


두 symbol은 모두 같지 않기 때문에 자바스크립트에서 개인 속성을 모의하는 데 편리하게 사용할 수 있습니다.symbol은 개체에 나타나지 않습니다.keys () 의 결과입니다. 따라서symbol을 명확하게 export하거나 Object를 사용하지 않는 한.getownPropertySymbols() 함수를 가져옵니다. 그렇지 않으면 다른 코드가 이 속성에 접근할 수 없습니다.

function getObj() {
  const symbol = Symbol('test');
  const obj = {};
  obj[symbol] = 'test';
  return obj;
}

const obj = getObj();

Object.keys(obj); // []

//   symbol  , 
obj[Symbol('test')]; // undefined

//   getOwnPropertySymbols()   symbol  
const [symbol] = Object.getOwnPropertySymbols(obj);
obj[symbol]; // 'test'
또 하나의 이유는 심볼이 JSON에 나타나지 않기 때문이다.stringify () 의 결과에서 정확히 말하면 JSON입니다.stringify () 는 symbol 속성 이름과 속성 값을 무시합니다.

const symbol = Symbol('test');
const obj = { [symbol]: 'test', test: symbol };

JSON.stringify(obj); // "{}"

총결산


Symbol로 개체 내부 상태를 표시하면 사용자 데이터와 프로그램 상태를 잘 격리할 수 있습니다.그것이 있으면, 우리는 더 이상 어떤 명명 약정이 필요하지 않을 것이다. 예를 들어 내부 속성은'$'로 시작한다.다음에 개인 속성을 정의해야 할 때 Symbol 유형을 사용해 보세요!
다음은 JavaScript 원시 데이터 형식 Symbol에 대한 상세한 내용입니다. JavaScript 원시 데이터 형식 Symbo에 대한 더 많은 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기