[JS]Symbolデータ型



最近、編集プログラムを勉強する時、このコードをたくさん使って、編集/編集プロトコルについては講義で知っていますが、Symbolはほとんど突然出てくるキーワードなので、今回の学習テーマはSymbolを選んで勉強しました.

実際、ES 5までJavaScriptのデータ型はNumberStringBooleanundefinednullobjectSymbol程度(もちろん、それ以外にも)あり、Symbolというデータ型は存在しなかった.

しかしES 6+にはBigIntBigIntが出現した.(9007199254740992)、簡単に言えば、これまでJSで正しく実現した数は2の53勝9007199254740992-1です.その後の数字は正確に計算できず、通常このような大きな数字はあまり使いにくいが、もちろん使用する必要がある瞬間もあり、これらの問題を解決するために発生したデータ型である.nを超える数にNumberを加えて使用します.しかし、一般的なBigIntのデータ型と一緒に計算することはできず、BigIntのタイプはSymbolのタイプ間でしか計算できません.
だからこれでいいのに、いったい심볼(symbol)は何なのか.

📝 Symbol( )

symbol()  データ型は元のデータ型の一種であり、심볼(symbol)関数である.  Symbol  タイプの値を返します.返されるすべての構成部品の値が一意です.
構成部品は、主に名前の競合のリスクのない唯一のオブジェクトを作成するpropertyキー(property key)に使用されます.
👇 How to use Symbol
const symbol = Symbol(); 
const hello = Symbol("Hello!");
Symbol()を使用するには、false関数を呼び出す必要があります.また、文字列はパラメータとして渡すことができますが、影響はありません.

📝 Symbol()プロパティ


前述したように、文字列はパラメータとして受け入れることができますが、影響はありません.つまり、文字列が同じであれば、同じ値では測定できません.
👇 Code Example:同じように見えますが、すべてSymbolに戻ります.
console.log(Symbol() === symbol); // false
console.log(Symbol() === Symbol()); // false
console.log(Symbol("Hello!") === hello); // false
これらによってSymbolのユニークな意味を感じることができます.
実際、JavaScriptデータ型の大きな特徴は、データ型の変換が非常に柔軟であることです.たとえば、開発者が意図せずに適切な変換を自動的に適用します.
const string = 'a' + 1;
console.log(string); // "a1"
これにより、文字列と数値を追加する必要がある場合、数値のデータ型を自動的に文字列に変換して追加することができます.しかしながら、helloは、このようなデータ変換が不可能なデータ型である.
したがって、先ほど作成したSymbol型変数に!型変数を追加したい場合は、すぐに構成部品値をstringに変換できないタイプエラーが出力されます.
👇 Code Example
const hello = Symbol("Hello!");
const hello2 = hello + '!'; 
// TypeError: Cannot convert a Symbol value to a string
また、Symbol型は基本列挙対象から除外される.オブジェクトを宣言する場合は、オブジェクトのpropertyをSymbolに指定できます.しかしその後、この項目に近づこうとするかfor.. inで巡るとSymbol型に近づくことができず、探索から除外される.そのため、PropertyKeyを隠そうとするときによく使われます.
const TYPE = Symbol('타입');
const FLAVOR = Symbol('맛');

const icecream = {
	[TYPE] : "아이스크림",
  	[FLAVOR] : "MINT CHOCOLATE",
  price : 3500,
}

const cupcake = {
	[TYPE] : "컵케이크",
  	[FLAVOR] : "Vanilla Cream",
  price : 5700,
}

console.log(icecream[FLAVOR], cupcake[FLAVOR]); 
// 접근 가능 : "MINT CHOCOLATE", "Vanilla Cream"
もちろん、TYPEFLAVORと宣言された値に直接アクセスして出力できますが、次の例では、これらの値は対応するナビゲーションに含まれていません.
for (const i in icecream) {
	console.log(`${i} : ${icecream[i]}`); // "price : 3500"
}

for (const c in cupcake) {
	console.log(`${c} : ${cupcake[c]}`); // "price : 5700"
Object.keys()Object.getOwnPropertyNames()により、上記の例のようにpriceのみにアクセスしてもよい.したがって、Symbolによって割り当てられたキー値にアクセスするには、Object.getOwnPropertySymbols()を使用する必要があります.
Object.getOwnPropertySymbols(icecream).forEach(i => console.log(i, icecream[i]));
// Symbol(타입) "아이스크림" 
// Symbol(맛) "MINT CHOCOLATE"
この場合、要素として宣言されたキー値のみが出力されるため、オブジェクト内のキー値とキー値が要素であるかどうかにかかわらず、すべてのキー値にアクセスして出力するにはReflect.ownKeys()を使用する必要があります.
Reflect.ownKeys(icecream).forEach(i => console.log(i, icecream[i]));
// price 3500 
// Symbol(타입) "아이스크림" 
// Symbol(맛) "MINT CHOCOLATE"

📝 Symbol.for() / Symbol.keyFor()


以前の素子特性では,素子を介して2つの変数に値を割り当てると,すなわち素子関数のパラメータに同じ文字列を加えると,素子もユニークな値を生成するので,この2つの変数は異なることが分かった.しかし、同じ文字列を含む変数を構成部品に作成するにはどうすればいいですか?この場合、Symbol.for()の方法を用いることができる.
  • Symbol.for():パラメータとして渡された文字列をキーとして使用し、保存キーとシンボル値のペアである전역 심볼 레지스트리でキーが存在するか否かを検索し、すでに存在する場合はキーを返し、存在しない場合は、新しく渡されたキーを使用して素子値を生成し、전역 심볼 레지스트리に保存し、値を返す.
    *グローバル構成部品レジストリ:JSエンジンが管理する構成部品値リポジトリ
  • const s1 = Symbol.for('hello, stranger');
    const s2 = Symbol.for('hello, stranger');
    
    console.log(s1 === s2); // true
  • Symbol.keyFor():Symbol.for()メソッドにより、グローバル構成部品レジストリに格納されているキー値を検索して抽出し、返します.
  • Symbol.keyFor(s1); // "hello, stranger"
    Symbol.keyFor(s2); // "hello, stranger"
    Symbol.keyFor(hello); // undefined
    既存のダイレクトコールSymbol()関数によって生成された要素値は、グローバル要素レジストリに格納されないため、undefined万しか出力されない.

    📝 Well-Known Symbol:標準拡張またはかわいいタイプ検証

    console.dir(Symbol)をコンソールウィンドウに入力すると、これらの結果が表示されます.これはjavascriptがデフォルトで提供するコンストラクションシンボル値で、Symbol関数のpropertyに割り当てられ、ECMAはWell-Known Symbolと呼ばれています.また、JavaScriptエンジンの内部アルゴリズムにも使用されます.

    +)
    ここで、Symbol.iteratorfor.. ofであり、ループ可能に構築された反復可能メソッドの鍵として使用され、Symbol.iteratorメソッドが呼び出されると、反復プロトコルに従ってこのウィジェットが返される.
    const range = {
    	[Symbol.iterator]() {
        	let start = 1;
            const end = 10;
            
            return {
            	next() {
                	return {value : start++, done: start > end + 1};
                }
            };
        }
      };
    
    for (const r of range) console.log(r); 
    コンストラクション時のイテレーションではなくオブジェクトをイテレーションのように動作させる場合は、Symbol.iteratorをキーとする方法をオブジェクトに追加してイテレーションを返し、上記の方法を使用します.

    n/a.結論


    コンポーネントは、何も繰り返さない定数値を生成します.したがって、既存のコードに影響を及ぼさずに新しいpropertyを追加し、最下位の互換性を確保するためにデータ型を導入することができます.

    ✨ References.


    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol
    https://poiemaweb.com/es6-symbol
    http://hacks.mozilla.or.kr/2015/09/es6-in-depth-symbols/
    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
    https://another-light.tistory.com/105
    https://pks2974.medium.com/javascript%EC%99%80-%EC%8B%AC%EB%B3%BC-symbol-bbdf3251aa28
    https://geundung.dev/83
    https://jongbeom-dev.tistory.com/138
    https://javascript.info/symbol#system-symbols