온보딩 3일차(2023.03.10) - 함수

최재홍·2023년 3월 13일
0

함수

함수에 대해서 공부하기 전에 몇 가지 용어를 정리할 필요가 있다.

  • 함수 호출 : 함수를 사용하는 것.
  • 매개변수 : 함수를 호출할 때는 괄호 내부에 여러 가지 자료를 넣는데 이를 매개변수라고 한다.
  • 리턴값 : 함수를 호출해서 최종적으로 나오는 결과를 리턴값 혹은 반환값이라고 한다.

함수는 코드의 집합을 나타내는 자료형이며, 기본 형태는 다음과 같다.

function () { }

함수의 장점은

  • 반복되는 코드를 한 번만 정의해놓고 필요할 때마다 호출하므로 반복 작업을 피할 수 있다.
  • 긴 프로그램을 기능별로 나눠 여러 함수로 나누어 작성하면 모듈화로 전체 코드의 가독성이 좋아진다.
  • 기능별(함수별)로 수정이 가능하므로 유지보수가 쉽다.

선언적 함수

일반적으로 함수는 위와 달리 이름을 가지고 사용되는데 이렇게 생성한 함수를 선언적 함수라고 한다.

function 함수명() {

}

선언적 함수는 기본적으로 다음 코드와 같은 기능을 수행한다.

let 함수명 = function () {};

매개변수와 리턴값

함수를 호출할 때 괄호 안에 적는 것을 매개변수 또는 인자(parameter)라고 한다. 그리고 함수의 최종 결과를 리턴값이라고 부른다. 모든 함수에 매개변수와 리턴값을 사용하는 것이 아니라 필요한 경우에만 매개변수와 리턴값을 사용한다.

매개변수와 리턴값을 갖는 함수는 다음과 같은 방법으로 만든다.

function 함수명(매개변수, 매개변수, 매개변수) {
  문장
  문장
  return 리턴값
}

매개변수(parameter)와 인수(argument)

  • 매개변수 혹은 인자는 함수 선언 방식 괄호 사이에 있는 변수이다.(선언 시 쓰이는 용어)
  • 인수는 함수를 호출할 때 매개변수 자리에 전달되는 값이다.(호출 시 쓰이는 용어)

지역 변수

함수 내에서 선언한 변수인 지역 변수(local variable)는 함수 안에서만 접근할 수 있다.

외부 변수

함수 내부에서 함수 외부의 변수인 외부 변수(outer variable)에 접근할 수 있다. 또한 외부 변수에 접근하는 것 뿐만 아니라 수정도 할 수 있다.

ex)

<script>
  let userName = 'John';
  
  function showMessage() {
  userName = "Bob"; // 외부 변수를 수정함
  
  let message = 'Hello ' + userName;
  alert(message);
  }
  
  alert(userName); // 함수 호출 전이므로 John이 출력됨
  
  showMessage();
  
  alert(userName); // 함수에 의해 Bob으로 값이 바뀜
</script>

화살표 함수

함수 표현식보다 단순하고 간결한 문법으로 함수를 만들 수 있는 방법이 있는데 이를 화살표 함수라고 한다.

let func = (arg1, arg2, ...argN) => expression

이렇게 코드를 작성하면 인자 arg1..argN를 받는 함수 func가 만들어진다. 함수 func는 화살표(=>) 우측의 표현식(expression)을 평가하고, 평가 결과를 반환한다.

let func = function(arg1, arg2, ...argN) {
  return expression;
};

위와 아래는 같은 함수를 의미한다.

  • 인수가 하나밖에 없다면 인수를 감싸는 괄호를 생략할 수 있다.
let double = n => n * 2;
  • 인수가 하나도 없을 때는 괄호를 비워놓으면 된다.
let sayHi = () => alert("안녕하세요!");

나머지 매개변수

상당수의 자바스크립트 내장 함수는 인수의 개수에 제약을 두지 않는다. 호출할 때 매개변수의 개수가 고정적이지 않은 함수를 가변 매개변수 함수라고 부른다. 자바스크립트에서 이러한 함수를 구현할 때는 나머지 매개변수라는 특이한 형태의 문법을 사용한다. 나머지 매개변수의 기본적인 사용 방법은 다음과 같다.

function 함수명 (...나머지 매개변수) { }

함수의 매개변수 앞에 마침표 3개(...)를 입력하면 매개변수들이 배열로 들어온다.

ex)

<script>
  function sample(...items) {
    console.log(items)
  }
  
  sample(1, 2)
  sample(1, 2, 3)
  sample(1, 2, 3, 4)
</script>

함수 정의 방법과 상관없이 함수에 넘겨주는 인수의 개수엔 제약이 없다.

function sum(a, b) {
  return a+b;
}

alert(sum(1,2,3,4,5));

함수를 정의할 때는 인수를 두개만 받도록 하고, 실제 함수를 호출할 때는 이보다 더 많은 여분의 인수를 전달했지만 에러가 발생하지 않는다. 다만 반환 값은 처음 두개의 인수만을 사용해 계산된다.

이렇게 여분의 매개변수는 그 값들을 담을 배열 이름을 마침표 세개 ...뒤에 붙여주면 함수 선언부에 포함시킬 수 있다. 이때 마침표 세개 ...는 "남아있는 매개변수들을 한데 모아 배열에 집어넣어라."는 것을 의미한다.

아래 예시에선 모든 인수가 배열 args에 모인다.

function sumAll(...args) { //args는 배열의 이름
  let sum = 0;
  
  for(let arg of args) sum += arg;
  
  return sum;
}

alert(sumAll(1)) // 1
alert(sumAll(1,2)) // 3
alert(sumAll(1,2,3)) // 6

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

나머지 매개변수는 일반적인 매개변수와 조합해서 사용할 수도 있다.

function 함수명(매개변수, 매개변수, ...나머지 매개변수) {}

ex)

<script>
  function sample(a, b, ...c) {
    console.log(a, b, c)
  }
  
  sample(1, 2)
  > 1 2 []
  sample(1, 2, 3)
  > 1 2 [3]
  sample(1, 2, 3, 4)
  > 1 2 [3, 4]
</script>

실행 결과에서 알 수 있듯이 함수를 호출할 때 매개변수 a, b가 먼저 들어가고, 남은 것들은 모두 c에 배열 형태로 들어간다.

전개 연산자

다음과 같이 매개변수로 배열을 입력할 수 없고 숫자를 입력해야 하는 함수가 있다고 가정하자.

min(52, 273, 32, 103)
min(52, 273, 32, 103, 275, 24, 57)

이때 배열 자료형으로 읽어들였다면 위와 같은 형태의 min() 함수를 어떻게 호출할 수 있을까?

const array = [1, 2, 3, 4]

기본적으로는 다음과 같이 배열 요소를 하나하나 전개해서 입력하는 방법 밖에 생각할 수 없다.

min(array[0], array[1], array[2], array[3])

이런 상황에 대비하고자 자바스크립트는 배열을 전개해서 함수의 매개변수로 전달해주는 전개 연산자를 제공한다. 전개 연산자는 다음과 같이 배열 앞에 마침표 3개(...)를 붙이는 형태로 사용한다.

함수명(...배열)

기본 매개변수

함수의 매개변수로 항상 비슷한 값을 입력하는 경우가 있다. 항상 같은 매개변수를 여러 번 반복해서 입력하는 것이 귀찮을 경우 매개변수에 기본값을 지정하는 기본 매개변수를 사용한다.

함수명(매개변수, 매개변수=기본값, 매개변수=기본값)

매개변수는 왼쪽부터 입력하므로 다음과 같이 함수를 작성하면 기본 매개변수의 의미가 없다. b에 값을 전달하기 위해서는 a에 값을 채워야 하기 때문이다.

function sample(a=기본값, b) {}

ex) 가령 wage와 hours를 입력하지 않고 실행하면 wage에 최저 임금이 들어가고, hours에 법정근로 시간 40시간이 기본 매개변수로 입력되게 만든다면 다음과 같다.

<script>
  function earnings (name, wage=8590, hours=40) {
  어쩌구저쩌구
  }
</script>

확인문제

  1. A부터 B까지 범위를 지정했을 때 범위 안의 숫자를 모두 곱하는 함수를 만들어보세요.
<script>
  function multiplyAll(A, B) {
    output = 1;
    if(A === B) {
      return A;
    } else if(A > B) {
      for(i = B; i <= A; i++) {
      output = output * i;
      }
    } else {
      for(i = A; i <= B; i++ ) {
      output = output * i;
      }     
    }
     return output;
  }
</script>

이 함수를 더 간결하게 선언해보기

<script>
  function multiplyAll(A, B) {
    let output = 1;
    const [start, end] = [Math.min(A, B), Math.max(A, B)];
    for (let i = start; i <= end; i++) {
      output *= i;
    }
    return output;
  }
</script>

  1. 다음 과정에 따라 최대값을 찾는 max() 함수를 만들어보세요.
  • 매개변수로 max([1,2,3,4])와 같은 배열을 받는 max() 함수를 만들어보세요.
<script>
  const max = array => {
    let output = array[0];
    for(i = 0; i < array.length; i++) {
      if(array[i] >= output) {
        output = array[i];
      }
    }
    return output;
  }
</script>
  • max(1,2,3,4)와 같이 숫자를 받는 max() 함수를 만들어보세요.
<script>
  const max = (...array) => {
    let output = array[0]
    for(i = 0; i < array.length; i++) {
      if(array[i] >= output) {
        output = array[i];
      }
    }
  return output;
}
</script>
  • max([1,2,3,4]) 형태와 max(1,2,3,4) 형태를 모두 입력할 수 있는 max() 함수를 만들어보세요.

나의 풀이)

<script>
  const max = (...array) => {
    let output;
    if(array[1] !== undefined) {
      output = array[0];
      for(i = 0; i < array.length; i++) {
        if(output <= array[i]) {
          output = array[i]
        }
      }
    } else {
      output = array[0][0];
      for(i = 0; i < array[0].length; i++) {
        if(output <= array[0][i]) {
          output = array[0][i];
        }
      }
    }
  return output;
  }
</script>

정답)

<script>
 const max = function(first, ...rests) {
   let output;
   let items;
 
   if(Array.isArray(first)) {
     output = first[0];
     items = first;
   } else if(typeof(first) === 'number') {
     output =first;
     items = rests;
   }
   for(i = 0; i < items.length; i++) {
     if(output < items[i]) {
       output = items[i];
     }
   }
   return output;
 }
</script>

0개의 댓글

관련 채용 정보