기호 원시 값은 다른 기호 원시 값의 값을 포함하여 다른 값과 충돌하지 않는 고유한 값을 나타냅니다. 동일한 문자로 구성된 두 문자열 프리미티브는 엄격히 동일하게 평가됩니다.
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
그러나 Symbol()
함수를 사용하여 만든 두 기호는 엄격히 동일할 수 없습니다.
Symbol() === Symbol()
> false
이 트레잇을 사용하면 기호를 객체의 고유한 속성 키로 사용할 수 있으므로 다른 코드가 객체에 추가할 수 있는 키와의 충돌을 방지할 수 있습니다.
const mySymbol = Symbol( "Desc" );
const myObject = {};
myObject[mySymbol] = "propSymbol";
myObject
> Object { Symbol("Desc"): "propSymbol" }
기호에는 세 가지 유형이 있습니다.
Symbol()
로 만든 기호Symbol.for()
를 사용하여 전역 기호 레지스트리에서 설정되고 검색되는 공유 기호- Symbol 객체의 정적 속성으로 정의된 '잘 알려진 기호' 이러한 기호에는 실수로 덮어쓸 수 없는 내부 메서드가 포함되어 있습니다.
Symbol()
는 설명 (또는 '기호 이름')을 선택적 인수로 허용합니다.
이러한 설명은 디버깅 목적으로 사람이 읽을 수 있는 라벨이며 결과의 고유성에 영향을 미치지 않습니다. Symbol
호출은 여러 호출의 설명이 동일하더라도 완전히 고유한 기호 프리미티브를 반환합니다.
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
다른 원시 데이터 유형과 마찬가지로 기호는 프로토타입에서 메서드와 속성을 상속합니다. 예를 들어 생성된 기호의 상속된 속성으로 설명에 액세스할 수 있습니다.
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
하지만 new
키워드를 사용하여 기호를 만들 수는 없습니다.
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
기호는 열거할 수 없습니다. 즉, 표준 메서드를 사용하여 기호 속성을 반복할 수 없습니다. getOwnPropertySymbols()
메서드는 객체의 기호 속성에 액세스할 수 있도록 합니다.
공유 기호
Symbol.for()
메서드는 지정된 문자열을 키로 사용하여 런타임 전반의 글로벌 기호 레지스트리에서 기존 기호를 조회하고 일치하는 기호가 있는 경우 이를 반환합니다. 키를 찾지 못하면 지정된 키로 기호를 만들고 전역 레지스트리에 추가합니다.
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
이러한 키는 작성자가 만든 Symbol
원시 형식에 할당된 설명과 기능적으로 겹치지 않습니다. 기호 레지스트리의 기호에 액세스하려면 먼저 for()
를 사용하여 기호를 만들어야 합니다.
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol.for( "String" );
> false
Symbol.for( "String" ) === Symbol.for( "String" );
> true
기호 레지스트리에서 기호의 키를 검색하려면 Symbol.keyFor()
를 사용합니다.
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
'잘 알려진' 기호
잘 알려진 기호는 Symbol
객체의 정적 속성으로, 각각 기호 자체입니다. 잘 알려진 기호는 JavaScript의 내장 메서드에 액세스하고 이를 수정하기 위한 고유한 속성 키를 제공하는 동시에 핵심 동작이 의도치 않게 덮어쓰이는 것을 방지합니다.
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
기호는 ES6에만 해당하는 기능이므로 이러한 기호 값은 개발자가 하위 호환성 문제를 일으키지 않고 JavaScript 동작을 수정할 때 '확장 포인트'로 사용하기 위한 것입니다.
잘 알려진 기호 값은 키를 변경 가능한 프로토타입과 구별하기 위해 @@
접두사로 스타일 지정되거나 %
로 래핑되는 경우가 많습니다. 예를 들어 @@match
(또는 %match%
)는 String.prototype.match
가 아닌 변경 불가능한 Symbol.match
에 대한 참조입니다.
이해도 확인
new
를 사용하여 기호를 만들 수 있나요?
다음 중 `잘 알려진` 기호를 설명하는 것은 무엇인가요?