본문 바로가기

IT Study./혼공JS

5장. 함수 - 1

 

 

 

혼공JS 5장 - 1

 

 

 


05-1 함수의 기본 형태

  • 함수를 알아보기 전에 몇 가지 용어를 정리해보자.
  • 함수를 사용하는 것을 함수 호출, 즉 '함수를 호출하다'라고 표현한다.
  • 함수를 호출할 때는 괄호 내부에 여러 가지 자료를 넣는데, 이러한 자료를 매개변수라고 부른다.
  • 그리고 함수를 호출해서 최종적으로 나오는 결과를 리턴값이라고 부른다.

 

 

<익명 함수>

  • 함수는 코드의 집합을 나타내는 자료형이며, 익명 함수는 말 그대로 함수의 이름이 없는 함수로 현대에 와서는 나중에 나올 선언적 함수보다 더 많이 사용된다.
  • 익명 함수의 기본 형태는 아래와 같다.
function () { }
  • 함수를 코드의 집합이라고 말하는 이유는 중괄호 {...} 내부에 코드를 넣기 때문이다.
  • 함수를 사용하면 좋은 점은 아래와 같다.
    • 반복되는 코드를 한 번만 정의해놓고 필요할 때마다 호출하므로 반복 작업을 피할 수 있다.
    • 긴 프로그램을 기능별로 나눠 여러 함수로 나누어 작성하면 모듈화로 전체 코드의 가족성이 좋아진다.
    • 기능별(함수별)로 수정이 가능하므로 유지보수가 쉽다.
  <script>
    // 변수를 생성합니다.
    const 함수 = function () {
      console.log('함수 내부의 코드입니다 ... 1')
      console.log('함수 내부의 코드입니다 ... 2')
      console.log('함수 내부의 코드입니다 ... 3')
      console.log('')
    }

    // 함수를 호출합니다.
    함수()
    함수()

    // 출력합니다.
    console.log(typeof 함수)
    console.log(함수)
  </script>
  • 결과는 아래와 같다.

익명 함수의 실행 결과

  • 함수는 코드의 집합이다. 그래서 함수를 실행하면 여러 코드를 한 번에 묶어서 실행할 수 있으며, 필요할 때마다 호출하여 반복적으로 사용할 수도 있다.
  • 함수의 자료형은 function이며 현재 코드에서 함수를 출력하면 f () { }라고 출력된다.
  • 이때 f는 함수를 나타내며, 함수를 출력했을 때 별다른 이름이 붙어있지 않은 것을 볼 수 있다.
  • 이처럼 이름이 붙어있지 않은 함수를 익명 함수(anonymous function)라고 표현한다.

 

  • 이름이 붙은 함수는 아래와 같이 표기된다.

이름이 있는 함수의 실행 결과

 


 

<선언적 함수>

  • 앞에서는 익명 함수를 알아보았고 이제 이름이 있는 함수인 선언적 함수를 알아보자.
  • 선언적 함수의 기본 형태는 아래와 같다.
function 함수() { }
  • 아래는 간단한 선언적 함수의 예제이다.
  <script>
    // 함수를 생성합니다.
    function 함수 () {
      // 점프!
      console.log('함수 내부의 코드입니다 ... 1')
      console.log('함수 내부의 코드입니다 ... 2')
      console.log('함수 내부의 코드입니다 ... 3')
      console.log('')
    }

    // 함수를 호출합니다.
    함수()
    함수()

    // 출력합니다.
    console.log(typeof 함수)
    console.log(함수)

  </script>
  • 결과는 아래와 같다.

  • 위 결과를 보면 익명 함수와 다르게 f 뒤에 '함수'라고 이름이 붙어져 있는것을 확인할 수 있다.

 


 

<매개변수와 리턴값>

  • 함수를 호출할 때 괄호 안에 적는 것을 매개변수라고 한다.
  • prompt() 함수를 사용할 때 매개변수로 message를 넣어야 한다. 그러면 prompt() 함수의 최종 결과는 문자열로 나온다.
  • 함수의 최종 결과를 리턴값이라고 부른다.
  • 앞에서 만든 '함수'라는 이름의 함수는 입력할 때 괄호 내부에 아무 것도 나오지 않는다. 모든 함수에 매개변수와 리턴값을 사용하는 것이 아니라 필요한 경우에만 매개변수와 리턴값을 사용한다.
  • 매개변수와 리턴값을 갖는 함수는 아래와 같이 사용한다.
function 함수(매개변수, 매개변수, 매개변수) {
  문장
  문장
  return 리턴값
}
  • 아래는 매개변수로 x를 넣으면 x2을 리턴하는 함수의 예제이다.
  <script>
    // 함수를 선언합니다.
    function f(x) {
      return x * x
    }

    // 함수를 호출합니다.
    console.log(f(3))
  </script>
  • 결과는 아래와 같다.

실행 결과

 


 

<기본적인 함수 예제>

 

윤년을 확인하는 함수 만들기

  • 보통 2월은 28일까지 있지만 몇년에 한 번 29일까지 있기도 하다.
  • 이런 해를 윤년(leap year)이라고 부르고 아래와 같은 특징이 있다.
    • 4로 나누어 떨어지는 해는 윤년이다.
    • 하지만 100으로 나누어 떨어지는 해는 윤년이 아니다.
    • 하지만 400으로 나누어 떨어지는 해는 윤년이다.
  • 윤년의 특징을 isLeapYear()이라는 이름의 함수로 구현해보자.
  <script>
    function isLeapYear(year) {
      return (year % 4 === 0) && (year % 100 !== 0) || (year % 400 === 0)
    }

    console.log(`2020년은 윤년일까? === ${isLeapYear(2020)}`)
    console.log(`2010년은 윤년일까? === ${isLeapYear(2010)}`)
    console.log(`2000년은 윤년일까? === ${isLeapYear(2000)}`)
    console.log(`1900년은 윤년일까? === ${isLeapYear(1900)}`)
  </script>
  • 결과는 아래와 같다.

윤년인지 확인하는 함수의 실행 결과

 

A부터 B까지 더하는 함수 만들기

  <script>
    function sumAll(a, b) {
      let output = 0
      for (let i = a; i <= b; i++) {
        output += i
      }
      return output
    }

    console.log(`1부터 100까지의 합: ${sumAll(1, 100)}`)
    console.log(`1부터 500까지의 합: ${sumAll(1, 500)}`)
  </script>
  • 결과는 아래와 같다.

실행 결과

 

최솟값을 구하는 함수 만들기

  <script>
    function min(array) {
      let output = array[0]
      for (const item of array) {
        // 현재 output보다 더 작은 item이 있다면
        if (output > item) {
          // output의 값을 item으로 변경
          output = item
        }
      }
      return output
    }

    const testArray = [52, 273, 32, 103, 275, 24, 57]
    console.log(`${testArray} 중에서`)
    console.log(`최솟값 = ${min(testArray)}`)
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 


 

<나머지 매개변수>

  • 호출할 때 매개변수의 개수가 고정적이지 않은 함수를 가변 매개변수 함수라고 부른다.
  • 자바스크립트에서 이러한 함수를 구현할 때는 나머지 매개변수(rest parameter)라는 특이한 형태의 문법을 사용한다.
  • 나머지 매개변수의 기본적인 사용 방법은 아래와 같다.
function 함수 이름(...나머지 매개변수) { }
  • 함수의 매개변수 앞에 마침표 3개(...)를 입력하면 매개변수들이 배열로 들어온다.
  • 나머지 매개변수의 작동을 확인할 수 있는 아래의 예제를 살펴보자.
  <script>
    function sample(...items) {
      console.log(items)
    }

    sample(1, 2)
    sample(1, 2, 3)
    sample(1, 2, 3, 4)
  </script>
  • 실행 결과는 아래와 같다.

나머지 매개변수의 실행 결과

 

  • 이전에 살펴본 min() 함수의 매개변수에 배열을 사용하지 않는 형태로 변경할 수 있다.
  <script>
    // 나머지 매개변수를 사용한 함수 만들기
    function min(...items) {
      // 매개 변수 items는 배열처럼 사용합니다.
      let output = items[0]
      for (const item of items) {
        if (output > item) {
          output = item
        }
      }
      return output
    }

    // 함수 호출하기
    console.log('min(52, 273, 32, 103, 275, 24, 57)')
    console.log(`= ${min(52, 273, 32, 103, 275, 24, 57)}`)
  </script>
  • 실행 결과는 아래와 같다.

min()의 실행 결과

 

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

  • 나머지 매개변수는 이름 그대로 나머지이며, 아래와 같이 일반적인 매개변수와 조합해서 사용할 수 있다.
function 함수 이름(매개변수, 매개변수, ...나머지 매개변수) { }
  • 아래와 같이 (a, b, ...c)를 매개변수로 갖는 함수를 살펴보자.
  <script>
    function sample(a, b, ...c) {
      console.log(a, b, c)
    }

    sample(1, 2)
    sample(1, 2, 3)
    sample(1, 2, 3, 4)
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 

  • 매개변수의 자료형에 따라 다르게 작동하는 min() 함수를 구현하려고 한다.
  • 먼저 매개변수로 들어온 자료형이 배열인지 숫자인지 확인할 수 있어야 한다.
  • 숫자 자료형은 typeof 연산자를 사용해서 확인할 수 있으며, 이를 배열에 사용할 경우 object(객체)라는 결과가 나온다.
  • 물론 typeof(배열) == 'object')와 같은 형태로 배열인지 확인할 수 있지만, 정확하게 배열인지 확인하려면 Array.isArray() 메소드를 활용해야 한다.
  • 이를 활용한 예제는 아래와 같다.
  <script>
    function min(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 (const item of items) {
        if (output > item) {
          output = item
        }
      }
      return output
    }

    console.log(`min(배열): ${min([52, 273, 32, 103, 275, 24, 57])}`)
    console.log(`min(숫자, ...): ${min(52, 273, 32, 103, 275, 24, 57)}`)
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 

전개 연산자

  • 이전 예제에서 min() 함수는 매개변수로 배열을 넣는 경우와 숫자를 넣는 경우 모두 대응했다.
  • 하지만 다른 사람들이 만든 함수도 모두 그럴 것이라는 보장이 없다.
  • 만약 매개변수로 배열을 입력할 수 없고 숫자를 입력해야 하는 함수가 있다고 한다면 array[0], array[1], ... 과 같이 배열 요소 하나하나를 전개해서 입력하는 방법밖에 생각할 수 없다.
  • 이러한 상활에 대비하고자 자바스크립트는 배열을 전개해서 함수의 매개변수로 전달해주는 전개 연산자(spread operator)를 제공한다.
  • 전개 연산자는 아래와 같이 배열 앞에 마침표 3개(...)를 붙이는 형태로 사용한다.
함수 이름(...배열)
  • 전개 연산자는 다양한 곳에 활용할 수 있으며, 아래의 간단한 예제를 살펴보자.
  <script>
    // 단순하게 매개변수를 모두 출력하는 함수
    function sample(...items) {
      console.log(items)
    }

    // 전개 연산자 사용 여부 비교하기
    const array = [1, 2, 3, 4]

    console.log('# 전개 연산자를 사용하지 않은 경우')
    sample(array)
    console.log('# 전개 연산자를 사용한 경우')
    sample(...array)
  </script>
  • 실행 결과는 아래와 같다.

전개 연산자의 실행 결과

  • 위의 결과를 보면 전개 연산자를 사용하지 않은 경우에는 4개의 요소가 있는 배열이 매개변수로 들어왔고, 전개 연산자를 사용한 경우 숫자가 하나하나 전개되어 매개변수로 들어오는 것을 볼 수 있다.

 


 

<기본 매개변수>

  • 함수의 매개변수로 항상 비슷한 값을 입력하는 경우에는 매개변수에 기본값을 지정하는 기본 매개변수를 사용한다.
  • 기본 매개변수는 아래와 같은 패턴으로 만든다.
function sample(a=기본값, b) { }
  • 매개변수로 시급과 시간을 입력받아 급여를 계산하는 함수를 만들어보자.
    • 함수 이름: earnings
    • 매개변수: name(이름), wage(시급), hours(시간)
    • 함수의 역할: 이름, 시급, 시간을 출력하고, 시급과 시간을 곱한 최종 급여 출력
  <script>
    function earnings (name, wage=8590, hours=40) {
      console.log(`# ${name} 님의 급여 정보`)
      console.log(`- 시급: ${wage}원`)
      console.log(`- 근무 시간: ${hours}시간`)
      console.log(`- 급여: ${wage * hours}원`)
      console.log('')
    }

    earnings('구름')

    // 시급 1만원으로 최대한 일하는 경우
    earnings('별', 10000)

    // 시급 1만원으로 52시간 일한 경우
    earnings('인성', 10000, 52)
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 

  • 기본 매개변수를 추가한 윤년 함수의 예제
  <script>
    function isLeapYear(year=new Date().getFullYear()) {
      console.log(`매개변수 year: ${year}`)
      return (year % 4 === 0) && (year % 100 !== 0) || (year % 400 === 0)
    }

    console.log(`올해는 윤년일까? === ${isLeapYear()}`)
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 

 

 


 

 

 

①구 버전 자바스크립트에서 가변 매개변수 함수 구현하기

  • 구 버전의 자바스크립트에서 가변 매개변수 함수를 구현할 때는 배열 내부에서 사용할 수 있는 특수한 변수인 arguments를 활용한다.
  • arguments는 매개변수와 관련된 여러 정보를 확인할 수 있고 배열과 비슷하게 사용할 수 있다.
  <script>
    /* arguments 사용 */
    function sample1() {
      console.log(arguments)
      for (let i = 0; i < arguments.length; i++) {
        console.log(`${i}번째 요소: ${arguments[i]}`)
      }
    }

    sample1(1, 2)
    sample1(1, 2, 3)
    sample1(1, 2, 3, 4)
    
    
    /* 나머지 매개변수 사용 */
    function sample2(...items) {
      console.log(items)
      for (let i = 0; i < items.length; i++) {
        console.log(`${i}번째 요소: ${items[i]}`)
      }
    }

    sample2(1, 2)
    sample2(1, 2, 3)
    sample2(1, 2, 3, 4)
    
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 


 

②구 버전 자바스크립트에서 전개 연산자 구현하기

  • 전개 연산자는 최신 버전의 자바스크립트에 추가된 기능이다.
  • 구 버전의 자바스크립트에서는 다음과 같이 apply() 함수를 사용한 굉장히 특이한 패턴의 코드를 사용했다.
  • 이 코드는 용도를 모르면 아예 이해할 수가 없으므로 아래의 예제를 확인하자.
  <script>
    // 단순하게 매개변수를 모두 출력하는 함수
    function sample(...items) {
      console.log(items)
    }

    // 전개 연산자 사용 여부 비교하기
    const array = [1, 2, 3, 4]
    console.log('apply() 함수 사용')
    console.log(sample.apply(null, array))
    console.log('전개 연산자 사용')
    console.log(sample(...array))
  </script>
  • 실행 결과는 아래와 같다.

실행 결과

 


 

③구 버전 자바스크립트에서 기본 매개변수 구현하기

  • 함수의 매개변수에 바로 값을 입력하는 기본 매개변수는 최신 자바스크립트에서 추가된 기능이다.
  • 구 버전의 자바스크립트에서는 일반적으로 아래와 같은 코드를 사용해서 기본 매개변수를 구현해야 했다.
function earnings (wage, hours) {
  wage = typeof(wage) != undefined ? wage : 8590
  hours = typeof(hours) != undefined ? hours : 52
  return wage * hours
}
  • 매개변수로 들어오는 값이 false또는 false로 변환되는 값(0, 빈 문자열 등)이 아니라는 게 확실하다면 다음과 같이 짧은 조건문을 사용해서 기본 매개변수를 구현할 수 있다.
function earnings (wage, hours) {
  wage = wage || 8590
  hours = hours || 52
  return wage * hours
}
  • 인터넷에는 구 버전의 자바스크립트로 작성된 참고 자료가 많다.
  • 구 버전에 대한 것도 기억해주면 다른 사람이 작성한 코드가 어떤 목적으로 작성했는지 쉽게 알 수 있다.

 

 

 

 

 

 


해당 글은 [혼자 공부하는 자바스크립트] 책을 토대로 공부한 내용을 기록하기 위하여 작성됨.

 


 

 

 

'IT Study. > 혼공JS' 카테고리의 다른 글

6장. 객체 - 1  (0) 2022.06.13
5장. 함수 - 2  (0) 2022.06.12
4장. 반복문 - 2  (0) 2022.06.10
4장. 반복문 - 1  (0) 2022.06.09
3장. 조건문 - 2  (0) 2022.06.08