[Node.js_6기 본캠프] Today I Learned_0814

2024. 8. 14. 20:24[Node.js_6기 본캠프 TIL]

▶ ES6, 일급객체로서의 함수, Map과 Set

JavaScript 기본 문법에 이어 , es6 문법에서 새로 추가된 문법에 대해 공부했다. 삼항 연산자나 구조 분해 할당 같은 개념들은 이전에 풀어보던 알고리즘 코드카타에서 종종 보던 것들이라 조금 익숙했다. 화살표 함수는 아직까지는 볼 때마다 조금씩 멍해지는 것 같다. 조금 더 다양한 문제들을 풀어보며 응용 가능할 때까지 완전히 이해할 시간이 필요하다.

 

1. ES6


// 2015년도 이전 -> var
// (1) ES6 -> let(변수), const(상수)

// (2) arrow function
function add() {}

var add = function () {};

var add = (x) => {
    return 1;
};

var add = (x) => 1;

// (3) 삼항 연산자
// condition ? true인 경우 : false인 경우
console.log(1 === 1 ? "참" : "거짓")
 

 

2. 구조 분해 할당 (destructuring)

 
// 배열이나, 객체의 속성

// (1) 배열의 경우
let [value1, value2 ] = [1, "new"]
console.log("1", value1) // 1 1
console.log("2", value2) // 2 2

let arr = ["value1", "value2"];
let [a, b, c] = arr;
console.log(a); // value1
console.log(b); // value2
console.log(c); // undefined

let arr2 = ["value1", "value2"];
let [d, e, f = 3] = arr;
console.log(d); // value1
console.log(e); // value2
console.log(f); // 3
// f = 3이라고 초기값을 설정해주었고, arr2에서 불러올 값이 없었기 때문.
// arr2 = ["value1", "value2", "value3"]가 되면 f는 3이 아니라 value3을 불러온다.

// (2) 객체인 경우
let user = {
    name: "asd",
    age: 42,
};

// 구조분해할당
let {name, age} = {
    name: "asd",
    age: 42,
};

console.log("name => ", name); // asd (객체가 아닌 string 타입)
console.log("age => ", age); // 42 (객체가 아닌 number 타입)

// 새로운 이름으로 할당
let user2 = {
    name: "qwe",
    age: 31,
};

let {name: newName, age: newAge} = user2;
console.log("newName =>", newName); // newName => qwe
console.log("newAge =>", newAge); // newAge => 31
 

 

3. 단축 속성명 (property shorthand)

 
const name = "asd";
const newAge = "30";

// key - value 페어를 잊지 말기
const obj = {
    name: name, // key와 value의 네이밍이 같을 경우, 'name: name'이 아니라 'name,'으로 단축할 수도 있다.
    age: newAge,
}

// 같은 값 예시
const obj2 = {name, newAge};
const obj3 = {name: name, newAge: newAge};



// 전개 구문 = spread operator
// destructuring과 함께 가장 많이 사용되는 ES6 문법 중 하나
let arr = [1, 2, 3];
let newArr = [...arr, 4];

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


// 객체
let user = {
    name: "asd",
    age: 30,
};

let user2 = {...user};

console.log(user); // { name: 'asd', age: 30 }
console.log(user2); // { name: 'asd', age: 30 }


// 나머지 매개변수(rest parameter)
// ...args: 나머지 arguments가 올 수 있음
// arg 앞에 ... 을 넣지 않으면 배열 형태로 나온다
function exampleFunc(a, b, c, ...args) {
    console.log(a, b, c); // 1 2 3
    console.log(...args); // 4 5 6 7
}

exampleFunc(1, 2, 3, 4, 5, 6, 7)


// 템플릿 리터럴(Template Literal)
// 백틱(``)은 따옴표("")와 동일하게 문자를 기입할 수 있으며, 함수도 들어갈 수 있다.
const testValue = "안녕하세요!";
console.log(`Hello World ${testValue}`);
 

 

4. 일급객체로서의 함수


// (1) 변수에 함수를 할당할 수 있다.
const say = function() {
    console.log("Hello!");
};

// (2) 함수를 인자로 다른 함수에 전달할 수가 있다.
// (2)-1. 콜백함수: 매개변수로써 쓰이는 함수
// (2)-2. 고차함수: 함수를 인자로 받거나 return하는 함수
// 콜백함수는 고차함수의 한 종류라고 할 수 있다.
function call(func) {
    // 매개변수로 받은 변수가 사실, 함수다.
    func();
}

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

callFunction(sayHello);


// (3) 함수를 반환할 수 있다.
function creationAdder(num) {
    return function(x) {
        return x + num;
    };
}

const addFive = creationAdder(5);
console.log(addFive(10)); // 15
 
//
 
const person = {
    name: 'John',
    age: 54,
    isMarried: true,
    sayHello: function() {
        console.log("Hello, My name is " + this.name);
    },
};

person.sayHello();
// sayHello에 화살표 함수를 사용할 경우, this. 가 인식되지 않는다
 
 
// 배열의 요소로 함수를 할당

const myArr = [
    function (a, b) {
        return a+b;
    }, // 0번째 요소
    function (a, b) {
        return a-b;
    }, // 1번째 요소
];

// 더하기
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);
console.log(multiplyByTwo(10));
// multiplyBy에 num 값을 2로 준 상태에서 x값을 10으로 주었기 때문에, 20이라는 값이 도출된다.
 

5. Map

 
// Map, Set의 목적: 데이터의 구성, 검색, 사용을 효율적으로 처리
// 기존의 객체 또는 배열보다 빠르고 효율적으로 처리하는 것

// (1) Map
// ~ Key / Value
// Key에 어떤 데이터타입(유형)도 다 들어올 수 있다.
// ~Map은 키가 정렬된 순서로 저장되기 때문이다.
// 검색, 삭제, 제거, 여부 확인 기능 제공

const myMap = new Map();
// 데이터 집어넣기(.set)
myMap.set('key', 'value');
// 데이터 검색하기(.get)
myMap.get('key')
 
// 
 
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' }

// Map은 Iterator 속성이 있기 때문에 keys(), values(), entries() 메소드를 사용하여 'for ~ of'라는 형태의 반복문을 사용할 수 있다.
for (const key of myMap.keys()) {
    console.log(key); // one two three
}

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

// map의 사이즈(길이)
console.log(myMap.size);

// key 기반 검색
console.log(myMap.has("two1")); // two1 이라는 key가 없는 상태이기 때문에 false

 

6. Set

 
// 고유한 값을 저장하는 자료구조
// 값만 저장한다
// 키를 저장하지는 않는다
// 값이 중복되지 않는 유일한 요소로만 구성된다
// 값 추가, 검색, 값 삭제, 모든 값 제거, 존재 여부 확인

const mySet = new Set();
mySet.add('value1');
mySet.add('value2');
mySet.add('value2');

console.log(mySet.size); // 2 (중복되는 값은 합쳐지기 때문에, value2를 두번 추가하더라도 한번만 카운팅 된다)

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

 

 

☆ (문제) 배열 연습하기

코딩테스트 연습 - 문자열 내 마음대로 정렬하기

 

문제를 처음 보았을 때, for문이나 strings[n], split 등이 떠올랐다. 근데 알파벳 순으로 어떻게 정리하지? js에도 sql의 order by 같은 함수가 있나? strings를 단어별로 쪼개고, 알파벳으로 또 쪼개고, 순서를 정리한 뒤 합치려고 하니 코드가 너무 복잡하고 길어질 것 같았다.

 

js 입문 단계이다 보니, 풀이/해설은 대충 생각했던 형태와 비슷했다. 여러번 쪼개는 것을 걱정했던 것과는 달리, strings[i][n] 로 string의 i번째 단어에서 n번째 알파벳을 바로 가져올 수 있다는 게 신기했다. 보통  strings[i] 까지만 쓰다보니, 해당 부분이 처음에 이해가 되지 않아 한참을 봐야 했다. 그리고 가장 어려웠던 알파벳순 정리는 sort로 해결할 수 있었다.

더보기

function solution(strings, n) {
    let result = [];

// 문자열 가장 앞 글자 붙인 문자 배열 만들기
    for (let i = 0; i < strings.length; i++) {
      strings[i] = strings[i][n] + strings[i];
    }

// 문자열 사전순 정렬
    strings.sort();

// 앞글자 제거 후 리턴
    for(let j = 0; j < strings.length; j ++) {
      strings[j] = strings[j].replace(strings[j][0],"");
      result.push(strings[j]);
    }

    return result;
}

 

역시나 복잡하고 헷갈리고 길었다. 예전에 다른 문제를 풀다가 .sort((a, b) => {}); 형태를 본 것 같은데 이 문제에 적용하면 더 간편해지지 않을까? 

 

더보기

function solution(strings, n) {
    return strings.sort((a, b) => {
        // a[n]이 b[n]보다 크면 1을 반환하고 // 내림차순
      if (a[n] > b[n]) return 1;
 
        // a[n]이 b[n]보다 작으면 -1을 반환하고 // 오름차순
      else if (a[n] < b[n]) return -1;
 
        // a[n]이 b[n]과 같으면 사전순으로 정렬한다.
      else return a > b ? 1 : -1;
    });
  }

 

출처: https://hstory0208.tistory.com/entry/javascript-Lv1-문자열-내-맘대로-정렬하기 [< Hyun / Log >:티스토리]

 

구글링에 답이 있었다. sort와 if 함수의 기능을 적극 활용해서 더 직관적으로 각 단어를 비교하고 배열을 가공할 수 있었다.

 

.sort((a, b) => {});에서 a와 b가 정확히 뜻하는 바가 헷갈렸는데 sort((next, prev)=>{});  라는 구조라고 한다. 즉, 배열이 ["dog", "cat"] 이라면 a는 "cat" b는 "dog"가 된다. 

 

위의 풀이 글을 보면 1을 반환하면 내림차순, -1을 반환하면 오름차순이고 a가 e보다 큰 값을 가진다. 이 부분은 잘 이해가 되지 않아서 일단 외우기만 하고 따로 이해가 될 때까지 공부해야 할 것 같다.

 

 

풀이를 보지 않고 처음부터 코드를 짜는 것이 점점 더 어려워지고 있다. 함수들에 대한 지식의 부족인지 경험의 부족인지... 아직 갈 길이 멀다...