본문 바로가기
매일 해내는 개발/자바스크립트

[자바스크립트] ES6 set, symbol 자료구조

by 해야지 2022. 11. 8.
반응형

set, symbol은 Javascript ES6에서 새롭게 도입한 데이터 구조

*map()

key와 value를 한 쌍으로 묶는다는 점에서 객체(Object)와 비슷하다


1. Set()

특징

1)  배열과 유사하다. 하지만 배열은 중복된 값을 가질 수 있지만 set은 같은 값을 중복해서 가질 수 없다.
2) 중복해서 같은 값을 추가해도 추가되지 않는다. 그래서 이러한 성질을 이용하여 중복을 제거하는 용도로 사용된다.
     ex) 복권번호(중복되면 안되는 항목에 적용)
3) 파이썬의 set과 유사하다.


사용법

1) 생성 : new

let arr1 = new Set();


2) 추가 : add

arr1.add("추가할 값");

 

3) 삭제: delete

arr1.delete("삭제할 값");


4) 초기화: clear

arr1.clear();


5) 생성과 동시에 값을 추가 하는 방법

let arr2 = new Set().add('X').add('Y');


6) 펼침 연산자 Spread

let testArr='korea';
console.log(...testArr);   //k o r e a 로 출력됨
console.log([...testArr]); //배열이 됨 ['k','o','r','e','a']
console.log([..."hello"]); //[ 'h', 'e', 'l', 'l', 'o' ]


set의 값에 접근하는 방법
*set은 배열처럼 인덱스로 접근할 수 없다.

let testArr = new Set().add('A').add('B')
testArr[0]  //undefined


1) 펼침연산자로 배열로 변경 후 인덱스로 접근

let testSet = new Set( [ "tiger", "lion", "dog", "cat" ] );
testSet3.add( "hippo" );
let arr = [...testSet]; 
console.log(arr[0]); // tiger


2) key() 메서드로 접근

const key_itr = testSet.keys();

console.log( key_itr.next().value );  // tiger
console.log( key_itr.next().value );  // lion
console.log( key_itr.next().value );  // dog
console.log( key_itr.next().value );  // cat


3) values() 메서드로 접근

const val_itr = testSet.values();

console.log( val_itr.next().value );  // tiger
console.log( val_itr.next().value );  // lion
console.log( val_itr.next().value );  // dog
console.log( val_itr.next().value );  // cat


4) for ... of 반복문으로 출력

for( let i of testSet ) {
    console.log( i );
}
//tiger
//lion
//dog
//cat
//hippo


set의 entries() 메서드

let testSet = new Set();

testSet5.add("홍길동");
testSet5.add("이순신");
testSet5.add("강감찬");

const entries = testSet5.entries();

for (let i of entries) {
  console.log(i);
}
//[ '홍길동', '홍길동' ]
//[ '이순신', '이순신' ]
//[ '강감찬', '강감찬' ]

2. Symbol()

-객체에 속성을 추가하거나 덮어씌워질 우려가 있다면 충돌을 피하기 위한 수단으로 사용할 수 있다.

-배열 객체에 어떤 속성을 넣고자 한다면 그리고 동시에 반복문에서 속성이 나타나지 않게 하고자 한다면(속성 은닉화를 원한다면) 심볼을 사용할 수 있다.


특징

1) 객체의 속성으로 사용한다.
2) 심볼의 사전적 의미 = 상징
    따라서 심볼형을 사용하면 유일무이한 값, 고유한 값을 가진다는 뜻
3) 변경 불가능한 불변값이다.
4) 기존 타입들(원시형과 참조형) 중 원시형에 새롭게 추가된 타입
     ① 원시형 : Number, String, Null, Indefined, Boolean, Symbol(ES6)
     ② 참조형 : Object(object, function, array...)
5) 왜 객체의 속성으로 심볼을 사용하지?
     충돌을 피하기 위해서(고유한 값을 만들기 때문에)
     예)

let arr = [1,2,3,4,5]
console.log(arr.length); //5 배열의 길이 즉 요소 수를 알 수 있는 내장된 속성

arr.length = 50;         //arr 배열에 length 속성을 정의하고 50을 할당
console.log(arr.length)  //50 내장된 속성이 있는데도 덮어써지는 문제가 발생함

//심볼을 사용하면
let arr2 = [1,2,3,4,5];
const length = Symbol('length');
arr2[length] = 50;      // arr2 배열의 length 속성에 50을 할당하여 내장된 속성과 구분을 지을 수 있음

console.log(arr2.length) //5
console.log(arr2[length) //50


사용법

1) new 연산자를 사용하지 않고 Symbole() 함수를 사용하여 생성

let symbol = Symbol();



2) Symbol()의 괄호 안은 비워두고 생성해도 되고, 문자열을 넣어서 생성해도 된다.

보통 이때 괄호 안에 넣는 문자열(description)은 단순 디버깅 용도이거나 단순 설명일 뿐, 고유한 값을 가지는데 있어서 어떤 영향을 끼치지는 않는다.
심볼은 매번 Symbol() 함수 호출 시 새로운 심볼 값을 생성해내기 때문에 description 인자는 심볼의 고유 값을 구분하지 못한다. 

let symbol2 = Symbol('personName');
let symbol3 = Symbol('personName');
//'personName' description과 관계 없이 symbol2와 symbol3는 각각 고유한 값으로 생성된다.
console.log(symbol2 === symbol3); //false


3) 심볼의 출력 형태

① 심볼 값은 문자열 형태로 변환할 수 없기 때문에 출력은 콘솔로만 가능

let symobl() = Symbole('age');
alert(symbol); // Uncaught TypeError
console.log(symbol) // Symbol(age)와 같은 형태로 출력됨

 

② 심볼형은 for .. in 구문으로 반복시 출력되지 않는다. (Symbol의 은닉성 보장)

- 일반 배열 객체에 속성을 추가하면 for .. in 반복문으로 출력 시 해당 속성도 같이 출력된다.

let arr = [1,2,3,4,5]
arr.someProperty = 10;

for(let i in arr){
	console.log(i); // 0,1,2,3,4,someProperty
}

- 심볼형으로 속성을 추가하면 무시된다.

let arr = [1,2,3,4,5]
let someProperty = Symbol('somProperty');
arr[someProperty] = 10;

for(let i in arr){
    console.log(i) // 0,1,2,3,4  -> someProperty 속성이 나타나 보이지 않고 인덱스만 출력됨
}

console.log(arr[someProperty]); //10
반응형

댓글