[TIL] JS : 구조 분해, 옵셔널 체이닝, 그 외 여러가지 메소드(forEach, map, find, filter, some, every, reduce...)

gyulhana·2021년 8월 12일
0

DEV-COURSE

목록 보기
6/10

21년 08월 12일의 소회

오늘의 목표는 모르는 채로 강의를 수강하기엔 도저히 무리인 것 같아서 구조분해와 옵셔널 체이닝에 대한 개인적인 학습을 하고자 했다. 하지만 시작하고 보니 어느새 filter, find 메소드까지 모두 처음부터 제대로 공부하게 됐음.. 이걸 진작에 알았어야 됐군요? 모르는 채로 강의를 들으려니 당연히 잉스러웠겠죠?! 아무튼 아직도 뭔가를 보고 있는데 대체 8일차 강의 언제 듣고 과제 시작할까요. 금요일까지 달려! 아무튼 이걸 첨부터 제대로 알고 있었으면 좋았을 텐데 이제라도 알아서 넘 기쁘다고 해야 되나 결과적으로 또 재밌다고 느끼고 있음.

재밌다고 느낄 때마다 하는 필기. 이건 이번 주 월요일의 필기다. 공부하면서 필기해놓은 거 보면 그 당시의 내 생각의 흐름이 그대로 보여서 가끔 다시 보면 너무 웃기다. 아무튼 새로운 걸 배우는 건 재밌는데 뭐 재밌다는 걸 더 표현할 말이 없다. 새로운 건 왜 다 재밌지? 설렐 때만 사랑이니까..(피카부) 그리고 요즘 좀 더 좋은 환경에서 공부를 하기 위해 노트북 거치대와 침대 쿠션을 장만했고 오늘 왕큰 베드테이블까지 장만했다. 춘식이도 있다. 물론 내가 산 건 베드테이블밖에 없다. 다들 개발 열심히 하라고 생일 기념으로 사준 거지만..^_^ 역시 뭐든 장비빨이니까 열심히 해야지. 춘식이는 눈물을 닦아조. 개롭히는 놈들 감안안도 (도대체 누가 괴롭히는데..)

춘식이와 생선. 기엽죠? 그만큼 춘식이가 푹신하단 뜻이시겠지.

아니 근데 TIL에 이렇게 일기를 써도 되나요? 몰라, 알게 뭐야. 업무도 아니고 제 마음입니다만. 재미 없는 TIL 읽다가 누가 이렇게 재미나게 살고 있다는 거 보면 재밌지 않나요? 전 그르트라구여.

막상 TIL 쓰려니 오늘 학습한 게 너무 많아서 언제 다 쓰나 싶지만 그래도 정리를 안 하면 금세 잊게 될 거 같아서 사부작 사부작 쓰려고 합니다. 일단 오늘 공부한 건 요정도. 정리는 이따가 멘토링 끝나고 할래.

📝 구조 분해 : Destructuring

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

배열과 객체에 사용할 수 있으며 다만 배열은 배열끼리, 객체는 객체끼리 사용해야 한다. 구조 분해 할당을 통해서는 temp라는 새로운 변수를 선언하지 않고도 어떤 두 변수에 할당된 값(배열이 아니라고 하더라도)들을 교환할 수 있다.

// destructuring example

📝 옵셔널 체이닝 : Optional Chaining

옵셔널 체이닝 연산자 ?. 는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽어낸다. 옵셔널 체이닝에서 객체의 프로퍼티에는 점 표기법을 통해 접근한다.

만약에 옵셔널 체이닝 연산자?.의 왼쪽이 true라면 그 이후의 프로퍼티 값을 반환하고 아니라면 undefined를 리턴한다. 그렇기 때문에 NULL 병합 연산자 ??와 함께 사용하여 undefined가 반환된 경우 다른 값을 반환하도록 하기도 한다.

const shop1 = {
  owner: 'gyuran',
  icecream: {
    flavor: 'Mint Chocolate',
    price: 3500,
  }
}

const shop2 = {
  owner : 'younghee',
  cookie: {
    flavor: 'Lemon Cream',
    price: 2500,
  }
}

function orderIce(shop) {
  console.log(shop.icecream?.flavor ?? 'There is no Ice Cream.');
  // is there any ice cream on the shop? 
  // if they're having any ice cream, return the flavor of it.
  // if there isn't it, return the sentence : 'There is no Ice Cream.'
}

orderIce(shop1); // Mint Chocolate
orderIce(shop2); // There is no Ice Cream.

📝 .forEach() / .map()

  • forEach :

    forEach는 주어진 callback을 배열에 있는 각 요소에 대해 오름차순으로 한 번씩 하며, 삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않는다. 그렇기 때문에 해당 구문이 실행 중인 상황에서도 배열에 요소를 추가할 수 있으나, 해당 요소에 대해서는 실행이 되지 않고 이를 통해 무한 루프에 빠지는 상황도 일어나지 않는다.

// forEach 코드
  • map :

    map은 callback 함수를 각각의 요소에 대해 한번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다. callback 함수는 배열 값이 들어있는 인덱스에 대해서만 호출되므로, 값이 삭제되거나 아직 값이 할당/정의되지 않은 인덱스에 대해서는 호출되지 않는다.
    3개의 파라미터를 받을 수 있다.

// map 코드
  • forEachmap의 차이 : forEach는 배열에 있는 각 요소에 대해 주어진 실행만을 할 뿐 어떤 값을 최종적으로 반환하지는 않으나 map같은 경우에는 해당 실행 결과들을 반환해 새로운 배열을 만든다는 것에 차이가 있다.

📝 .filter() / .find()

  • filter :

    filter()는 배열 내 각 요소에 대해 한 번 제공된 callback 함수를 호출해, 해당 조건에 만족하는 모든 요소들을 배열로 반환한다.

// filter 코드
  • find :

    find()는 callback 함수가 true를 반환할 때까지 해당 배열의 각 요소에 대해서 callback 함수를 실행하고, 이 조건을 만족하는 요소를 발견하는 즉시 해당 요소의 값 하나를 반환하고 메소드 실행을 종료한다. 만약 이 조건을 만족하는 요소가 배열에 없다면 undefined를 반환하게 된다.

// find 코드

📝 .some() / .every()

someevery 메소드는 다른 메소드들과 달리 어떤 값을 반환하거나 실행하지 않고 해당 조건을 만족하는지, 아닌지에 대한 true/false만 반환한다.

  • some :

    some은 callback이 true를 반환하는 요소를 찾을 때까지 배열에 있는 각 요소에 대해 한 번씩 callback 함수를 실행하며 해당하는 요소를 발견한 즉시 true를 반환한다.

  • every :

    every는 callback이 false를 반환하는 요소를 찾을 때까지 배열에 있는 각 요소에 대해 한 번씩 callbackFn 함수를 실행하며 해당하는 요소를 발견한 경우 즉시 false를 반환한다.
    만약 모든 값에서 true을 반환하면 true를 반환합니다.

결과적으로 둘의 차이는 some 메소드는 배열 내에 해당 조건을 만족하는 요소가 하나라도 있는지를 확인하는 것이고 every 메소드는 배열 내 모든 요소들이 해당 조건을 만족하는지 확인하는 것이다.

다만, 빈 배열을 할당 받은 경우에 everyfalse를 반환할 요소가 없기 때문에 true값을 반환하게 되고 sometrue를 반환해줄 해당 조건을 만족하는 요소가 하나도 없기 때문에 flase를 반환하게 된다.

const shops = [
  { name: 'sweets', menu: ['아이스크림', '아이스크림', '아이스크림', '아이스크림'] },
  { name: 'zenjero', menu: ['아이스크림', '아이스크림', '과자', '아이스크림'] },
  { name: 'cecez', menu: ['아이스크림', '케이크', '아이스크림', '아이스크림'] },
  { name: 'boygirl', menu: ['아이스크림', '아이스크림', '아이스크림', '아이스크림'] },
];

// using every method
function iceCream1(shop) {
  const checking = shop.menu.every((t) => t === '아이스크림');
  const message = checking // === true 
  ? `가게 ${shop.name}에는 아이스크림만 판매합니다.` 
  : `가게 ${shop.name}에는 아이스크림이 아닌 다른 메뉴도 있어요.`;
	console.log(message);
}

console.log('--------every method-------');
shops.forEach((shop) => iceCream1(shop));


// using some method
function iceCream2(shop) {
  const checking = shop.menu.some((t) => t !== '아이스크림');
  const message = checking // === true 
  ?  `가게 ${shop.name}에는 아이스크림이 아닌 다른 메뉴도 있어요.`
  : `가게 ${shop.name}에는 아이스크림만 판매합니다.`;
	console.log(message);
}

console.log('--------some method-------');
shops.forEach((shop) => iceCream2(shop));

📝 .reduce()

reduce() 메소드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다. reduce 메소드에는 네 가지 파라미터가 들어갈 수 있다.

  • acc : accumulator, 누산기
    직전에 동작한 콜백함수가 리턴한 값을 전달받는 파라미터
    그러나 코드가 첫번째로 동작할 때는 이전에 리턴된 값이 없기 때문에 함수에서 두번째 아규먼트를 통해 어떤 값으로 시작할지 초기 값을 할당해줄 수 있다. 물론 이 초기값 할당이 이루어지지 않는다면 배열의 맨 처음 값을 초기 값으로 할당하게 되고 메소드 실행시에는 배열의 그 다음 인덱스부터 실행하게 된다.

  • cur : current value, 현재 값

  • idx : index, 현재 인덱스

  • src : source, 원본 배열

const something = [1, 2, 3, 4, 5];

const reducing = something.reduce((acc, cur, idx, src) => {
return acc + cur; // 누적된 값 + 현재 값
}, 0); //초기 값 할당

console.log(reducing); // 15

reduce 메소드는 실제로 어떻게 동작할까?

// 이 코드를 보자!

*Error : 에러도 객체다!

  • Type Error

  • Syntax Error : 코드에 문법 에러가 있다면 그 코드는 처음부터 실행되지 않고 에러를 메세지를 띄운다.

  • Reference Error

  • throw

  • try, catch, finally





예시 코드 입력은 나중에 할래요. 너무 지치고 힘들어(^_ㅠ) 그래도 하루만에 머리에 이만큼의 개념을 때려넣은 나 자신에게 칭찬을.. (●ˇ∀ˇ●) 8일차 강의 듣고 잘 수 있겠지? 오늘 급 놀라운 지점 애초에 컴퓨터 언어라는 걸 첨 배운 것도 4월 중순에서야지만..(탱자탱자) JS라는 언어를 공부하기 시작한지 2달도 안 됐음^_ㅠ 당연히 잘 할 리 없는 게 당연한 시기라고 생각하며 위안을 또 하고 꼭!!!!!!!!!! 과정 끝날 때에는 짱이 돼 있겠어!!!!!

와중에 달력을 보니 6월에 세운 하반기 계획이 네 개 있는데 그 중 두 개인 중국어 공부 다시 시작하기와 개발 교육 과정에 들어오기 두개는 벌써 완성했다! 정처기 필기랑 운전 연수하기만 하면 되는데 할 시간 있을지는 미지수.

profile
친절한 하루를 선물하고 싶은 사람

0개의 댓글