[TIL] ES6 문법 / 일급 객체로서의 함수 / Map과 Set

·2023년 10월 13일
0

TIL

목록 보기
4/85
post-thumbnail

오늘 배운 것

1. 각종 ES6 문법

(1) 구조 분해 할당(destructuring)

  • 구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식이다.

배열의 경우

let [value1, value2] = [1, "new"];
console.log(value1); // 1
console.log(value2); // new

let arr = ["val1", "val2", "val3"];
let [a, b, c, d = "val4"] = arr; // d 는 'val4'로 초기화
console.log(a, b, c, d); // val1 val2 val3 val4
  • 구조분해할당에서 d를 "val4"로 초기화 했더라도, arr 배열에서 arr[3]을 "val5"로 할당했다면, "val5"가 우선이다.
let arr = ["val1", "val2", "val3", "val5"];
let [a, b, c, d = "val4"] = arr; // d 는 'val4'로 초기화
console.log(a, b, c, d); // val1 val2 val3 val5
  • 할당되지 않은 변수가 있다면 undefined 가 저장된다.
let arr = [1, 2, 3];
let [a, b, c, d] = arr;

console.log(a, b, c, d); // 1 2 3 undefined

객체의 경우

let user = { name: "hyewon", age: 15 };
let { name, age } = user;
console.log(name, age); // hyewon 15
  • 다음과 같이 새로운 이름으로 할당할 수도 있다.
let user = { name: "hyewon", age: 15 };
let { name: newName, age: newAge } = user;
console.log(newName, newAge); // hyewon 15
  • 다음과 같이 새로운 속성을 추가해줄 수도 있다.
let user = { name: "hyewon", age: 15 };
let { name, age, birthday = "today" } = user; // birthday 는 'today'로 초기화
console.log(name, age, birthday); // hyewon 15 today
  • 배열과 마찬가지로 user 라는 객체에 birthday 라는 key가 이미 있다면, 그 값이 우선이다.
let user = { name: "hyewon", age: 15, birthday: "yesterday" };
let { name, age, birthday = "today" } = user; 
console.log(name, age, birthday); // hyewon 15 yesterday

(2) 단축 속성명(property shorthand)

  • 원래는 다음과 같이 써야하지만, 더 짧은 표기법을 사용해 동일한 결과를 얻을 수 있다.
const name = "hyewon";
const age = 20;

const obj = {
  name: name,
  age: age,
};

console.log(obj); // { name: 'hyewon', age: 20 }
  • key와 value가 동일하면 한번만 쓸 수 있다. (한개는 생략 가능)
const name = "hyewon";
const age = 20;

const obj = {
  name,
  age,
};

console.log(obj); // { name: 'hyewon', age: 20 }

(3) 전개 구문(Spread operator)

  • 구조 분해 할당과 함께 가장 많이 사용되는 ES6문법 중 하나이다.
  • 이 구조를 벗어버리고 새로운 구조를 입힐 때 많이 사용된다.

배열의 경우

let arr = [1, 2, 3];

console.log(arr); // [ 1, 2, 3 ]
console.log(...arr); // 1 2 3

let newArr = [...arr, 4];
console.log(newArr); // [1,2,3,4]

객체의 경우

let user = { name: "hyewon", age: 21 };
let user2 = { ...user, isMarried: false };

console.log(user2); // { name: 'hyewon', age: 21, isMarried: false }

(4) 나머지 매개변수 (Rest parameter)

function exampleFunc(a, b, c, ...args) {
  console.log(a, b, c); // 1 2 3
  console.log(...args); // 4 5 6
  console.log(args); // spread(...)를 빼주면 배열 형태! [ 4, 5, 6 ]
}
exampleFunc(1, 2, 3, 4, 5, 6);

(5) 템플릿 리터럴 (Template literals)

  • 여러 줄로 이뤄진 문자열과 문자 보간기능을 사용하게 만들어 주는 문자열 리터럴 표현식이다.
  • 백틱(`) 과 ${}로 표현한다.
  • 멀티 라인을 지원한다.
const value = "javascript";
console.log(`hello ${value}!`); // hello javascript!


2. 일급 객체로서의 함수

일급객체(First-class Object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.

  • 함수가 일급 객체로 취급되기 때문에, 우리는 함수를 매우 유연하게 사용할 수 있다.

(1) 변수에 함수를 할당

  • 함수는 변수에 할당할 수 있다.
const sayHello = function() {
  console.log('Hello!');
};

sayHello(); // "Hello!" 출력

(2) 함수를 인자로 다른 함수에 전달

  • 함수가 값으로 취급되기 때문에, 다른 함수의 인자로 전달할 수 있다.
  • 콜백 함수 : 매개 변수로서 쓰이는 함수
  • 고차 함수 : 함수를 인자로 받거나 반환하는 함수
    (즉, 콜백함수는 고차함수에 포함되는 개념)
function callFunction(func) {
  func();
}

const sayHello = function() {
  console.log('Hello!');
};

callFunction(sayHello); // "Hello!" 출력

(3) 함수를 반환

  • 함수의 return값이 함수일 수 있다.
function createAdder(num) {
  return function (x) {
    return x + num;
  };
}

const addFive = createAdder(5); 
// const addFive = function (x) { return x + 5; };

console.log(addFive(10)); // 15가 출력된다.

(4) 객체의 프로퍼티로 함수를 할당

const person1 = {
  name: "john",
  age: 31,
  isMarried: true,
  sayHello: function () {
    console.log(`Hello My name is ${this.name}`); //this는 자기자신 객체을 가리킨다.
  },
};
person1.sayHello(); // Hello my name is john

const person2 = {
  name: "john",
  age: 31,
  isMarried: true,
  sayHello: () => {
    console.log(`Hello My name is ${this.name}`); //this는 자기자신 객체을 가리킨다.
  },
};

person2.sayHello(); // Hello! My name is undefined
  • 화살표 함수로 바꾸면 this.nameundefined가 나온다!
  • 화살표 함수는 this를 바인딩하지 않기 때문 (3주차 때 배워보자!)

(5) 배열의 요소로 함수를 할당

  • 함수는 배열의 요소로 할당될 수 있다.
const myArr = [
  function (a, b) {
    return a + b;
  },
  function (a, b) {
    return a - b;
  },
];
// 배열 인덱스 쓰고 괄호로 함수 호출 (매개변수 포함해서)
console.log(myArr[0](1, 3)); // 4
console.log(myArr[1](10, 7)); // 3
  • 함수를 일급 객체로 다룰 수 있다는 것은, 함수를 다양하게 조합할 수 있다는 것을 의미한다.
  • 새로운 함수를 반환하는 함수를 작성하면, 함수를 조합하여 더 복잡한 기능을 구현할 수 있다.
  • 이것을 활용하면 코드를 더욱 간결하게 작성할 수 있으며, 유지 보수도 쉬워진다.
function multiplyBy(num) {
  return function (x) {
    return x * num;
  };
}

function add(x, y) {
  return x + y;
}

const multiplyByTwo = multiplyBy(2);
// const multiflyByTwo = function(x) { return x * 2 }

const multiplyByThree = multiplyBy(3);
// const multiflyByThree = function(x) { return x * 3 }

console.log(multiplyByTwo(10)); // 20
console.log(multiplyByThree(10)); // 30

const result = add(multiplyByTwo(5), multiplyByThree(10)); 
console.log(result); // 40

3. Map과 Set

  • JavaScript에서 객체와 배열을 이용하면 다양하고 복잡한 프로그래밍을 할 수 있지만, 여전히 현실세계의 여러가지 문제들을 프로그래밍적으로 반영하기엔 많이 부족하다.
  • 이러한 한계를 극복하고자 비교적 최근에 등장한 자료구조가 MapSet이다.
  • 이 자료구조는 데이터의 구성, 검색, 사용을 객체나 배열보다 효율적으로 처리할 수 있기 때문에 많이 각광받고 있다.

(1) Map

  • Map 은 키-값 쌍을 저장하는 객체와 비슷하다.
  • Map은 각 쌍의 키와 값을 저장하며, 객체와 달리 키로 사용할 수 있는 모든 유형을 사용할 수 있다. (키에 어떤 데이터 타입도 다 들어올 수 있다. 객체는 문자열만 가능.)
  • Map은 키가 정렬된 순서로 저장되기 때문에 추가한 순서대로 반복할 필요가 없다.
  • new Map() – 맵을 만든다.
  • map.set(key, value) – key를 이용해 value를 저장한다.
  • map.get(key) – key에 해당하는 값을 반환한다.. key가 존재하지 않으면 undefined를 반환한다.
  • map.has(key) – key가 존재하면 true, 존재하지 않으면 false를 반환한다.
  • map.delete(key) – key에 해당하는 값을 삭제한다.
  • map.clear() – 맵 안의 모든 요소를 제거한다.
  • map.size – 요소의 개수를 반환한다.

Map의 생성 및 사용

const map1 = new Map();

map1.set('a', 1);
map1.set('b', 2);
map1.set('c', 3);

console.log(map1.get('a'));
// Expected output: 1

map1.set('a', 97);

console.log(map1.get('a'));
// Expected output: 97

console.log(map1.size);
// Expected output: 3

map1.delete('b');

console.log(map1.size);
// Expected output: 2

Map의 반복

  • Map에서는 keys(), values(), entries() 메소드를 사용하여 키, 값 및 키-값 쌍을 반복할 수 있다.

💡 [for …of 반복문]
for of 반복문은 ES6에 추가된 새로운 컬렉션 전용 반복 구문이다. for of 구문을 사용하기 위해선 컬렉션 객체가 [Symbol.iterator] 속성을 가지고 있어야만 한다. (직접 명시 가능)

const myMap = new Map();
myMap.set("one", 1);
myMap.set("two", 2);
myMap.set("three", 3);

console.log(myMap.keys()); // [Map Iterator] { 'one', 'two', 'three' }
for (const key of myMap.keys()) {
  console.log(key);
} // one two three

console.log(myMap.values()); // [Map Iterator] { 1, 2, 3 }
for (const value of myMap.values()) {
  console.log(value);
} // 1 2 3

console.log(myMap.entries()); // [Map Entries] { [ 'one', 1 ], [ 'two', 2 ], [ 'three', 3 ] }
for (const entry of myMap.entries()) {
  console.log(entry);
} // [ 'one', 1 ], [ 'two', 2 ], [ 'three', 3 ]

Map의 크기와 존재 여부 확인

  • Map의 크기를 확인하려면 size 속성을 사용한다.
  • 특정 키가 Map에 존재하는지 여부를 확인하려면 has() 메소드를 사용한다.
console.log(myMap.size); // 3 
console.log(myMap.has("two")); // true

(2) Set

  • Set은 고유한 값을 저장하는 자료 구조
  • Set은 값만 저장하며, 키를 저장하지 않는다.
  • Set은 값이 중복되지 않는 유일한 요소로만 구성된다.

Set의 생성 및 사용

  • 새로운 Set을 만들려면 Set() 생성자를 사용한다.
  • Set에 값을 추가하려면 add() 메소드를 사용한다.
  • Set에서 값을 검색하려면 has() 메소드를 사용한다.
const mySet = new Set();
mySet.add('value1');
mySet.add('value2');
console.log(mySet.has('value1')); // true 출력

Set의 반복 / 크기 및 존재 여부 확인

  • Set에서는 values() 메소드를 사용하여 값을 반복할 수 있다.
  • Set의 크기를 확인하려면 size 속성을 사용한다.
  • 특정 값을 Set에서 검색하여 존재하는지 여부를 확인하려면 has() 메소드를 사용한다.
const mySet = new Set();
mySet.add('value1');
mySet.add('value2');
mySet.add('value2');
mySet.add('value3');

console.log(mySet.size); // 3이 출력된다. 중복된 값인 value2는 1개로 카운트.
console.log(mySet.has("value2")); // true 출력
console.log(mySet.has("value4")); // false 출력

for (const value of mySet.values()) {
  console.log(value);
} // value1 value2 value3

느낀점

기존에 알던 내용도 있었고, 모르던 내용도 있었다. 1주차 내용보다는 확실히 어려워진 느낌. 2주차 숙제로 문자열 관련된 알고리즘 문제 하나 풀어봤는데 힌트 참고해서 겨우겨우 풀었다.. 하하😂

profile
느리더라도 조금씩, 꾸준히

0개의 댓글