언어

Functions (JavaScript)

adawn 2025. 3. 14. 16:27

출처: https://javascript.info/function-basics

 

Functions

 

javascript.info

 

 

함수

 

자바스크립트에서 함수는 스크립트의 여러 위치에서 비슷한 동작을 반복 수행할 필요가 있을 때 사용함.

예를 들어 방문자가 로그인하거나 로그아웃할 떄 멋진 메시지를 보여줘야 한다면 , 함수를 사용하면 코드 중복 없이 해당 메시지를 여러 번 호출할 수 있음.

함수는 프로그램의 주요 " 빌딩 블록 " 임. 

한 번 정의한 함수를 여러 번 호출하여 동일한 동작을 실행할 수 있음.

 

우리는 이미 alert(message) , prompt(message , default)와 confirm(question)같은 내장 함수의 예를 보았음. 

하지만 우리는 직접 함수를 만들수도 있음.

 

함수 선언

함수를 생성하는 가장 기본적인 방법은 함수 선언문(function declaration)을 사용하는 것

문법은 다음과 같음 : 

 

function showMessage() {
  alert( 'Hello everyone!' );
}

 

먼저 function 키워드를 쓰고 

그 다음 함수 이름을 지정하며 

괄호 안에는 매개변수 목록(쉼표로 구분됨, 위 예제에서는 비어 있음)이 옴.

마지막으로 중괄호 {...}안에 함수 본문 (코드)이 위치함. 

 

일반적인 형태는 다음과 같음 .

 

function name(parameter1, parameter2, ... parameterN) {
  // 본문(body)
}

 

정의한 함수는 이름을 통해 호출할 수 있음 예를 들어 : 

 

function showMessage() {
  alert( 'Hello everyone!' );
}

showMessage();
showMessage();

 

 

위와 같이 showMessage()를 호출하면 함수 내의 코드가 실행되며 , 여기서는 메시지가 두 번 출력됨.

이 예제는 함수의 주요 목적 중 하나인 코드 중복 제거를 잘 보여줌. 

메시지나 출력 방식을 변경할 때 한 군데만 수정하면 되기 때문임.

 

지역 변수 (Local variables)

함수 내부에서 선언된 변수는 해당 함수 내부에서만 유효함.

 

예시 : 

 

function showMessage() {
  let message = "Hello, I'm JavaScript!"; // 지역 변수

  alert( message );
}

showMessage(); // "Hello, I'm JavaScript!" 출력

alert( message ); // <-- 오류! message 변수는 함수 내부에서만 유효함

 

외부 변수 (Outer variables)

함수는 외부에 선언된 변수에도 접근할 수 있음.

 

예시 : 

let userName = 'John';

function showMessage() {
  let message = 'Hello, ' + userName;
  alert(message);
}

showMessage(); // "Hello, John" 출력

 

함수는 외부 변수를 완전히 읽을 수 있으며 , 수정할 수도 있음.

 

예를 들어:

 

let userName = 'John';

function showMessage() {
  userName = "Bob"; // (1) 외부 변수를 변경함

  let message = 'Hello, ' + userName;
  alert(message);
}

alert( userName ); // 함수 호출 전: "John"

showMessage();

alert( userName ); // 함수 호출 후: "Bob", 함수가 외부 변수의 값을 변경함

 

주의 : 만약 함수 내부에서 같은 이름의 변수를 다시 선언하면, 해당 함수는 내부의 변수를 우선 사용하고 외부 변수는 무시하게 됨.

 

예시 :

 

let userName = 'John';

function showMessage() {
  let userName = "Bob"; // 지역 변수 선언

  let message = 'Hello, ' + userName; // "Bob" 사용됨
  alert(message);
}

showMessage();

alert( userName ); // "John", 외부 변수는 변경되지 않음

 

전역 변수(Global variables)

함수 외부에서 선언된 변수(예: 위의 외부 변수 username)는 전역 변수라고 하며 , 특별한 경우를 제외하면 모든 함수에서 접근할 수 있음. 

그러나 전역 변수의 사용은 최소화하는 것이 좋은 습관임. 

최신 코드에서는 전역 변수의 사용을 줄이고 , 대부분의 변수는 함수 내부에 위치함. 

다만, 프로젝트 전체의 데이터를 저장할 때 전역 변수가 유용할 수 있음. 

 

매개변수 (Parameters)

함수에 데이터를 전달할 떄 매개변수를 사용함.

 

아래 예제에서 함수는 두 개의 매개변수 from과 text를 갖음 : 

 

function showMessage(from, text) { // 매개변수: from, text
  alert(from + ': ' + text);
}

showMessage('Ann', 'Hello!'); // "Ann: Hello!" 출력
showMessage('Ann', "What's up?"); // "Ann: What's up?" 출력

 

함수가 호출될 때 전달된 값들은 해당 매개변수에 복사되어 함수 내부에서 사용됨.

또 다른 예제 : 외부 변수 from을 함수에 전달한 후 , 함수 내부에서 매개변수 from의 값을 변경해도 외부 변수는 변경되지 않음.

 

function showMessage(from, text) {
  from = '*' + from + '*'; // 매개변수 from을 예쁘게 변경함

  alert( from + ': ' + text );
}

let from = "Ann";

showMessage(from, "Hello"); // 출력: "*Ann*: Hello"

alert( from ); // "Ann", 함수 내부에서 수정한 값은 외부에 영향을 주지 않음

 

참고 : 함수에 전달되는 값을 인수(argument)라고 부르며 함수 선언 시 나열하는 매개변수 (parameter)와 구분됨.

 

즉 함수 showmessage 는 두 개의 매개변수를 가지고 선언되고 , 호출될 때 두 개의 인수 , 예를 들어 from 과 "hello"가 전달된다 라고 표현할 수 있음.

 

함수에 선언된 것은 매개 변수 , 매개 변수의 전달되는 값을 인수라고 함.

 

기본값(Default values)

함수를 호출할 때 인수가 제공되지 않으면, 해당 매개변수의 값은 undefined가 됨.

예를 들어 앞서 사용한 함수 showMessage(from , text)를 단일 인수로 호출하면 : 

 

showMessage("Ann");

 

오류가 발생하지 않으며 , 출력은 "Ann: undefined" 됨. 

매개변수 text가 전달되지 않았으므로 undefined가 됨. 

 

 매개변수에 기본값을 지정할수도 있음. 이는 매개변수 선언 시 = 기호를 사용하여 지정함. :

function showMessage(from, text = "no text given") {
  alert( from + ": " + text );
}

showMessage("Ann"); // "Ann: no text given" 출력

 

만약 인수가 undefined로 전달되더라도 기본값이 사용됨 : 

showMessage("Ann", undefined); // "Ann: no text given" 출력

 

기본값은 복잡한 표현식도 될 수 있으며 , 매개변수가 전달되지 않은 경우에만 평가되어 할당됨. 

예:

 

function showMessage(from, text = anotherFunction()) {
  // 인수가 없으면 anotherFunction()이 실행되고 그 결과가 text에 할당됨
}

 

기본값은 복잡한 표현식도 될 수 있으며, 매개변수가 전달되지 않은 경우에만 평가되어 할당됨.

 

여기서 text = anotherFunction() 을 이야기함.

 

 

기본 매개변수의 평가

자바스크립트에서는 함수가 호출될 때마다 , 해당 매개변수가 전달되지 않으면 기본값이  평가됨.

 

예를 들어 위 코드에서 text 매개변수가 전달되면 anotherFunction()은 실행되지 않지만 전달되지 않으면 매번 실행이 됨.

 

이전 버전의 자바스크립트에서 기본값 지정

몇 년 전에는 자바스크립트가 기본 매개변수 문법을 지원하지 않았기 때문에 , 다음과 같이 직접 undefined를 체크하는 방식으로 기본값을 지정했음.

 

function showMessage(from, text) {
  if (text === undefined) {
    text = 'no text given';
  }

  alert( from + ": " + text );
}

 

여기선 text가 undefined 일 때 즉 아무것도 할당이 되지 않았을 떄를 처리해줌.

 

또는 OR 연산자(||)를 사용하기도 했음. :

 

function showMessage(from, text) {
  // text가 falsy하면 기본값을 할당함 (빈 문자열 ""도 기본값으로 간주됨)
  text = text || 'no text given';
  // ...
}

 

대체 기본 매개변수

경우에 따라 함수 선언 후에 매개변수의 기본값을 설정할 수 도 있음.

 

function showMessage(text) {
  // ...

  if (text === undefined) { // 매개변수가 전달되지 않은 경우
    text = 'empty message';
  }

  alert(text);
}

showMessage(); // "empty message" 출력

 

또는 OR 연산자를 사용할 수 있음:

 

function showMessage(text) {
  // text가 undefined이거나 falsy하면 'empty'로 설정
  text = text || 'empty';
  // ...
}

 

모던 자바스크립트 엔진에서는 nullish 병합 연산자 (??)를 지원하므로 0과 같은 falsy 값들을 정상적인 값으로 취급할 때는 더 나은 선택임 : 

 

function showCount(count) {
  // count가 undefined 또는 null이면 "unknown" 출력
  alert(count ?? "unknown");
}

showCount(0);      // 0 출력
showCount(null);   // "unknown" 출력
showCount();       // "unknown" 출력

 

값을 변환하기 (Returning a value)

함수는 실행 결과로 값을 호출한 곳에 반환할 수 있음. 

가장 간단한 예로 두 값을 더하는 함수를 들 수 있음 : 

 

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

let result = sum(1, 2);
alert( result ); // 3 출력

 

return문을 만나면 함수의 실행은 즉시 종료되고 , 반환된 값은 호출한 코드에 전달됨.

하나의 함수 안에 여러 개의 return 문이 있을 수도 있음. 예를 들어 : 

 

function checkAge(age) {
  if (age >= 18) {
    return true;
  } else {
    return confirm('Do you have permission from your parents?');
  }
}

let age = prompt('How old are you?', 18);

if ( checkAge(age) ) {
  alert( 'Access granted' );
} else {
  alert( 'Access denied' );
}

 

함수 내에서 값 없이 return을 사용하면 , 함수는 즉시 종료되며 undefined를 반환함.

 

예를 들어 : 

 

function showMovie(age) {
  if ( !checkAge(age) ) {
    return;
  }

  alert( "Showing you the movie" );
  // ...
}

 

또한 , 함수에서 반환 값이 없으면 암묵적으로 undefined가 반환됨 : 

 

function doNothing() { /* 아무 작업도 하지 않음 */ }

alert( doNothing() === undefined ); // true

 

빈 return은 return undefined; 와 동일 : 

 

function doNothing() {
  return;
}

alert( doNothing() === undefined ); // true

 

주의 : 긴 표현식을 여러 줄에 걸쳐 반환하려고 할 떄 , return과 반환값 사이에 줄바꿈을 넣으면 자바스크립트는 자동으로 세미콜론을 추가하여 빈 값을 반환하게 됨.

 

올바른 예 : 

 

return (
  some + long + expression
  + or +
  whatever * f(a) + f(b)
);

 

반드시 반환 값이 return 과 같은 줄에 시작하도록 하거나 , 괄호를 사용

 

한 함수는 한 가지 동작만 수행하기 

함수는 그 이름이 암시하는 작업만 수행해야 하며 , 그 이상의 부수 효과가 없어야 함.

예를 들어 , 두가지 독립적인 작업은 보통 각각 별도의 함수로 분리하는 것이 좋음.

함께 호출되더라도 , 각 작업은 개별 함수로 구현하고 , 필요시 이를 묶는 또 다른 함수를 만들면 됨.

 

예시 : 

 

getAge 함수는 단순히 나이를 반환하기만 해야 하며 , 동시에 alert를 호출하면 안됨. 

createForm 함수는 폼을 생성하고 반환해야 하며 , 문서에 직접 추가하는 등의 부수 효과가 없어야 함. 

checkpermission 함수는 단순히 권한을 검사하여 결과를 반환해야 하며 , 그 결과를 화면에 출력하면 안됨. 

 

이러한 규칙은 함수 이름에 내포된 의미를 명확하게 하고 , 팀 내에서 일관된 코딩 스타일을 유지하는데 도움을 줌.

 

초단기 함수 이름

자주 사용되는 함수의 경우 , jQuery의 $나 Lodash의 _ 와 같이 아주 짧은 이름을 사용하는 경우도 있음.

하지만 이는 예외이며 , 일반적으로 함수 이름은 간결하면서도 설명적이어야 함.

 

함수는 곧 주석과 같다 

함수는 짧고 하나의 동작만 수행해야 함. 

만약 하나의 동작이 너무 크다면 , 여러 개의 작은 함수로 나누는 것이 좋음.

함수를 별도로 분리하면 테스트와 디버깅이 쉬어지며 , 함수 자체가 훌륭한 주석 역할을 함. 

예를 들어 , n이하의 소수를 출력하는 두가지 버전의 showPrimes(n) 함수가 있다고 함. 

 

첫 번째 버전은 레이블을 사용함 : 

 

function showPrimes(n) {
  nextPrime: for (let i = 2; i < n; i++) {

    for (let j = 2; j < i; j++) {
      if (i % j == 0) continue nextPrime;
    }

    alert( i ); // 소수 출력
  }
}

 

두번째 버전은 소수 여부를 검사하는 별도의 함수 isprime(n)을 사용함 : 

 

function showPrimes(n) {

  for (let i = 2; i < n; i++) {
    if (!isPrime(i)) continue;

    alert(i);  // 소수 출력
  }
}

function isPrime(n) {
  for (let i = 2; i < n; i++) {
    if ( n % i == 0) return false;
  }
  return true;
}

 

두번째 버전이 훨씬 이해하기 쉬움. 코드 조각 대신 , 함수 이름 isPrime이 수행하는 작업을 바로 알 수 있기 때문임.

때때로 재사용할 의도가 없더라도 , 코드를 구조화하고 가독성을 높이기 위해 함수를 만드는 것이 좋음. 

 

과제 

1.다음 함수는 매개변수 age가 18보다 크면 true를 반환하고 , 그렇지 않으면 확인창(confirm)을 띄워 그 결과를 반환함.

 

function checkAge(age) {
  if (age > 18) {
    return true;
  } else {
    // ...
    return confirm('Did parents allow you?');
  }
}

 

아래와 같이 else를 제거한 경우와 동작이 달라질까? 

 

function checkAge(age) {
  if (age > 18) {
    return true;
  }
  // ...
  return confirm('Did parents allow you?');
}

 

안 달라진다.

 

2. 다음 함수는 매개변수 age가 18보다 크면 true를 반환하고 , 그렇지 않으면 확인창 (confirm)을 

띄워 그 결과를 반환함. 

 

function checkAge(age) {
  if (age > 18) {
    return true;
  } else {
    return confirm('Did parents allow you?');
  }
}

 

이 함수를 if 문 없이 한 줄로 동일한 동작을 하도록 작

 

짠 코드 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        age = prompt("나이 입력","입력")
        checkAge()


    

    function checkAge(age){
        return age > 18 ? true : confirm('Did parents allow you?')
    }

       







    </script>
</body>
</html>

 

다른 예시 

OR (||)을 이용한 방법 

function checkAge(age) {
  return (age > 18) || confirm('Did parents allow you?');
}

 

3. 두 숫자 a와 b 중 작은 값을 반환하는 함수 min(a,b)를 작성

 

 

짠 코드 : 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        a = prompt(" a를 입력","a")
        a = Number(a)

        b = prompt(" b를 입력","b")
        b = Number(b)

        result = min(a,b)
        alert(result)

        function min(a , b){
            if(a > b){
            return b}

            if(a < b){
                return a
            }
        }

    </script>
</body>
</html>

 

4.함수 pow(x,n)을 작성하여 x를 n번 곱한 값을 반환하는 프로그램 만들기

 

짠 코드 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        x = prompt(" x를 입력","x")
        x = Number(x)

        n = prompt(" n를 입력","n")
        n = Number(n)

        value = pow(x,n)

        alert(value)

        function pow(x , n){
            let result = x

            for(let i = 1; i < n;i++){

                result *= x


            }

            return result

        }



    </script>
</body>
</html>