본문 바로가기
항해99/온보딩 스터디

[항해99] 온보딩 스터디 - 4일차 TIL

by junvely 2023. 3. 10.

🦄 온보딩 스터디 4일차 TIL

✨03/09 : 목표 : JS 기초 5파트 함수


📒강의 노트 정리

01 함수

1.익명함수(함수 표현식)와 선언적(함수 선언식) 함수 => 함수 표현식, 선언식 차이(함수 호이스팅)

- 익명 함수 => function() { ... }

function() {...}
const func = function() {...}

- 선언적 함수 => function func() { ... }

function func() {...}

 

- true / false 등 불린값을 리턴하는 함수명은 보통  is~ 라고 명명한다.

 

2. 나머지 매개변수

- 매개변수 앞에 ...를 입력 시 매개변수를 배열로 받을 수 있다.(가변적인 매개변수를 받을 때)

function array(...items) {
  console.log(items); //[10, 5, 7, 2, 45, 5]
  console.log(items[2]) // 7
}

console.log(array(10, 5, 7, 2, 45, 5));

- 일반 매개변수와 나머지 매개변수 조합

function sample(a, b, ...c) { //나머지 매개변수는 배열로
  console.log(a, b, c); // 1 2 [ 3, 4, 5 ]
}

sample(1, 2, 3, 4, 5);

function sample(a, ...b) {
  console.log(a, b);
}

sample([1, 2, 3, 4, 5]); // [ 1, 2, 3, 4, 5 ] []
sample(1, 2, 3, 4, 5); // 1 [ 2, 3, 4, 5 ]

- type of 로 배열을 검사하면 'object'로 나온다. => 어떤 자료가 배열인지 검사하려면 Array.isArray()를 사용한다.

 

 

3. 스프레드(...)문법 => 나머지 매개변수(...array) 를 이용하면 숫자가 하나하나 들어온다.

sample(array); // [Array[4]
sample(...array); // [1,2,3,4]

// 스프레드 문법으로 배열의 요소들을 복사하여 객체로도 생성 가능
const array = ["a", "b", "c", "d"];
const object = { ...array }; // { '0' : a, '1' : b, ... '3' : d}
console.log(object);

 

 

4. 기본값 매개변수

기본값 매개변수를 설정해 놓을 수 있다(따로 매개변수로 부여하지 않을 시, 기본값으로 대체된다).

function today(year, today=new Date().getToday()) {...}
console.log(today(2023)) // 2023, 오늘 날짜가  출력 된다.

 

 

02 함수 고급

 

1. 타이머 함수

1) setTimeout(콜백, 시간) => 특정 시간 후에 콜백함수 한 번 호출

setTimeout(() => {
    console.log("1초 후 한 번 실행");
  }, 1000);

2) setInterval(콜백, 시간) => 특정 시간 간격마다 콜백함수 호출

setInterval(() => {
    console.log("2초 간격으로 실행");
  }, 2000);

활용 예제)

 let id;
  let count = 0;

  id = setInterval(() => {
    console.log("1초 간격마다 실행");
    count++;
    console.log(count);
  }, 1000);

  setTimeout(() => {
    console.log("타이머를 종료합니다");
    clearInterval(id);
  }, 3000);

 

2. IIFE (즉시 실행 함수) 

- 전역 스코프에서 선언한 변수는 후에 중복이나 덮어씀에 의한 위험성이 있다. 이를 즉시 실행 함수로 한번 감싸주어 스코프를 한번 더 씌움으로서 이러한 위험성으로 부터 방지할 수 있다.

(() => {콜백})()

 

 

3. ❗익명함수(함수 표현식)와 선언적함수(함수 선언식) 의 차이

1) 익명 함수(함수 표현식) => 의도적, 순차적인 코드 실행, 변수에 담아 값으로 활용 가능

=> 순서에 의존적일 경우, 의도한 순서로 실행해야 할 때, 어떤 값을 리턴하여 값으로 활용할 때 유용하게 사용 => 현업에서는 대부분 익명 함수 사용 (안전)

2) 선언적 함수(함수 선언식) => 함수 호이스팅 => 순서에 관계없이 선언도 하기 전에 호출하더라도 항상 최상위에 선언된 것으로 간주되어 문제없이 실행 됨 => 클래스 객체 내부에서 메소드로 활용할 때 주로 많이 사용했었다. 

 

1. 자바스크립트 엔진이 함수를 언제 생성하는지, 호출할 수 있는지 => 함수 호이스팅

함수 선언문은 스크립트 실행 준비 단계에서 생성되기 때문에, 함수 선언문이 정의되기 전에도 호출 가능(함수 호이스팅)하다. 같은 블럭 내 어느 때든 접근할 수 있다. 반면 함수 표현식으로 정의한 함수는 함수가 선언되기 전에 접근하는 게 불가능 하다. 표현식은 실행 흐름이 표현식에 다다랐을 때 생성 된다. 따라서 표현식이 정의되기 전에 함수를 호출 할 수 없다.

 

2. 스코프 => 함수 선언문은 함수가 선언된 코드 블록 안에서만 유효하기 때문에 블록 밖에서는 함수에 접근하지 못한다(클래스의 메소드 같이 외부에서는 접근 불가).  반면 함수 표현식은 블록 내에 존재하는 어디서든 접근이 가능하다(변수에 담긴 일반 함수)

- 만약 같은 이름의 익명 함수와 선언적 함수를 사용했을 경우, 선언적 함수가 먼저 생성되고, 그 후 순서에 따라 익명 함수가 생성되기 때문에 익명 함수에 의해 덮어 씌워지게 된다. 따라서 같은 이름의 함수를 사용하면 안되고, 순서를 가늠하기 어려운 선언적 함수보다 우리가 원하는 순서대로 활용 가능한 익명 함수가 더 선호 되는 것이다. => var 호이스팅으로 인해 더 이상 var를 사용하지 않는 이유와 같다.

 

 

🔥확인 문제 풀어보기(오답 or 중요도 높은 문제)

let result = 1;
  function multi(start, end) {
    for (let i = start; i <= end; i++) {
      result *= i;
    }
    return result;
  }

  multi(1, 5);
  console.log(result); //120

 

const max = function (array) {
    let output = array[0];

    for (let item of array) {
      if (item < output) {
        output = item;
      }
    }

    return output;
  };

  console.log(max([5, 4, 3, 2, 1]));

- 2번 문제

const max = function (...array) {
    let output = array[0];

    for (let item of array) {
      if (item < output) {
        output = item;
      }
    }

    return output;
  };

  console.log(max(5, 4, 3, 2, 1));

- 3번 문제 내 풀이)

  const max = function (first, ...last) {
    let output;
    let items;

    if (Array.isArray(first)) {
      output = first[0];
      for (let item of first) {
        if (item > output) {
          output = item;
        }
      }
    } else {
      items = [first, ...last];
      output = items[0];
      for (let item of items) {
        if (item > output) {
          output = item;
        }
      }
    }

    return output;
  };

  console.log(max([1, 2, 3, 4]));
  console.log(max(1, 2, 3, 4));

- 3번 문제 정답 )

{
  const max = function (first, ...last) {
    let output;
    let items;

    if (Array.isArray(first)) {
      output = first[0];
      items = first;
    } else if (typeof first === "number") {
      output = first;
      items = last;
    }
    for (let item of items) {
      if (item > output) {
        output = item;
      }
    }

    return output;
  };

 

let numbers = [273, 25, 75, 52, 103, 32, 57, 24, 76];

  // 홀수만 추출
  const array1 = numbers.filter((num) => num % 2 !== 0);
  console.log(array1);

  // 100이하의 수만 추출
  const array2 = numbers.filter((num) => num <= 100);
  console.log(array2);

  // 5로 나눈 나머지가 0인 수만 추출
  const array3 = numbers.filter((num) => num % 5 === 0);
  console.log(array3);

 

const array = ["사과", "배", "귤", "바나나"];

  // for in 반복문 => forEach로 변경
  array.forEach((val, idx) => {
    console.log(idx);
  });

  // for of 반복문 => forEach로 변경
  array.forEach((val) => {
    console.log(val);
  });

 

 

✅ 배운 점

함수는 자바스크립트의 꽃이라고도 한다. 그 만큼 가장 중요한 부분인데, 기존에 알던 내용들과 섞이고.. 지금까지 알던 내용이 사실 조금 다른 내용이고.. 했던 부분들이 좀 있어서 많이 헤맸다. 하지만 계속 보다 보니 지금까지 두서없이 공부했던 내용들이 오늘에서야 조금 정리가 되는듯 하다.

특히 함수 표현식과 선언식에 대한 개념이.. 선언 방식이 참 비슷하기도 해서 어려웠었는데 오늘 기술 매니저님이 말씀해 주신 함수의 개념적인 부분 => 선언문(조건문..반복문..값이 없고 로직만 존재하는), 표현식(값을 나타내기 위한), 선언식(로직 + 함수 호이스팅 + 내부 스코프에서만)과 표현식(로직 + 변수에 담아 값으로도 활용 가능 + 외부 스코프에서 접근 가능)의 개념을 좀 더 명확하게 알게돼서 다행이었다.

표현식과 선언식의 차이점은 1. 함수 생성시기와 호출시기 => 호이스팅(가장 중요한, var호이스팅과 같이) 2. 접근 가능한 스코프 범위 => 선언식은 선언된 블록 내부에서만, 표현식은 정의 후 어디서든 접근 가능 하다는 점이 있다.

즉시 실행 함수를 공부하다 보니 전역 스코프에서의 변수명의 중복이나 덮어씌움 등등의 위험으로부터 모듈화하여 벗어나기 위해서도 쓰인다고 하는데, 문득 프로젝트에서 사용했었던 웹팩이라는 모듈 번들러가 생각났다. 이 역시 전역 스코프에서의 변수명의 중복이나 덮어씌움 등등의 위험으로부터 모듈화(지역 스코프)하여 위험 요소를 방지할 수 있는 아주 중요한 역할을 하고 있었다는 사실도 깨달았다.

추가로 뜬금없지만, 어제 기술 매니저님께 과제로 내주셨던 table에 배열 자료들을 html요소로 넣는 부분에서 innerHTML과 createElement()의 차이점에 대해 질문하였다.

innerHTML과 document.createEelement의 차이점 => createElement의 경우, dom객체로 생성되어 생성된 dom객체에 객체 메소드를 사용할 수 있고, innerHTML의 경우, dom요소가 아닌, string요소이기 때문에 객체 메소드를 사용하지 못하고 string 문자열관련 속성과 메소드를 사용할 수 있다.(*객체가 아닌데 어떻게 속성과 메소드를 사용할 수 있을까?) => 둘의 접근 방법도 다르다. createElement는 메소드이기 때문에 .createElement()로 접근해야 하고, innerHTML은 string이기 때문에 =' '로 접근할 수 있다. 이 차이를 몰라서 innerHTML()로 접근하다 안돼서 굉장히 애먹었다.. => innerHTML으로 인해 생성된 html요소는 renderTree에 포함될까?

항상 궁금했던 부분이었는데 차이점에 대해 좀 알게 된 것 같아 뿌듯했다. 내일도 화이팅 하자..!🙌

 

 

➕보완할 점

더 공부하고 싶은 부분 :  배열 자료를 HTML 요소로 넣기 연습,

*String이나 Number 등은 primitive타입 기본 자료형인데, 객체가 아닌데도 어떻게 속성과 메소드를 사용할 수 있을까?

=> 자바스크립트는 기본 자료형의 속성과 메소드를 호출할 때 일시적으로 기본 자료형을 객체로 승급시킨다. 그래서 속성과 메소드를 사용할 수 있다. 이러한 승급은 일시적이다. 따라서 기본 자료형에 속성을 추가하면 추가되는 것 처럼 보이지만 실제로는 추가되지 않는다.