함수

함수(Function)는 특정 기능을 수행하기 위한 코드 블록입니다. 함수는 프로그래밍에서 중요하며 빈번히 활용되는 요소 중 하나입니다. 이 문서에서는 함수를 선언하고 사용하는 방법을 소개합니다.

함수가 무엇인가요?

함수가 무엇인지에 대해 생소할 수도, 익숙할 수도 있습니다. '함수'가 등장하는 가장 대표적인 분야로 수학이 있습니다.

f(x)=2x+3f(x) = 2x + 3

여기에서 f(x)f(x)는 일차 함수입니다. f(x)f(x)는 매개변수 xx를 가지며, f(1)=5f(1) = 5, f(3)=9f(3) = 9, ...와 같이 xx의 값에 따라 특정한 값을 도출합니다. JavaScript에서의 함수 또한 특정한 값을 입력받고, 특정한 값을 반환할 수 있습니다.

사실 프로그래밍에서 함수는 단순히 값을 반환하는데에만 초점을 맞추지 않습니다—특정한 기능을 수행하기 위한 목적이므로 필요에 따라 매개변수가 없는 함수를 만들 수도, 반환값이 없는 함수를 만들 수도 있습니다.

함수 선언

일반적으로 함수의 선언은 function 키워드를 사용합니다.

function 함수이름(매개변수1, 매개변수2, ..., 매개변수N) {
    // 기능의 동작을 위한 코드
    return 반환값;
}

매개변수는 필요하지 않을 경우 생략할 수 있습니다. return 또한 필요하지 않을 경우 사용하지 않아도 됩니다. return이 존재하지 않을 경우 해당 함수는 반환값이 존재하지 않는 함수가 됩니다.

함수 선언의 예로, 두 숫자의 합을 반환하는 함수(이름은 add로 하겠습니다)는 아래와 같이 선언할 수 있습니다.

function add(num1, num2) {
    let result = num1 + num2;
    return result;
}

함수 호출

함수 호출은 다음과 같이 합니다.

함수이름(인자1, 인자2, ..., 인자N);

인자(Argument)는 호출하는 함수에 전달하는 값으로, 함수 선언에 사용한 매개변수에 대응됩니다. 예를 들어,

function add(num1, num2) {
    let result = num1 + num2;
    return result;
}

이 함수를 호출해 4와 6의 합을 구하고자 할 경우

add(4, 6);

와 같이 작성합니다. 인자 46은 각각 add 함수의 매개변수 num1num2에 대응됩니다. 그러므로 함수 호출 시 4 + 6의 값인 10을 반환하게 됩니다.

return: 반환하고 종료하기

계속 살펴봤듯이, return은 지정한 반환값을 반환합니다. 하지만 return은 동시에 함수의 실행을 끝냅니다.

function writeLog() {
    Log.i("함수가 호출되었습니다.");
    return "함수의 실행을 종료합니다.";
    Log.i("로그를 추가로 작성합니다.");
}

Log.i()는 스크립트 로그를 작성하는 메소드입니다. 위 함수를 실제로 테스트하기 위해 코드를 작성해봅시다.

const bot = BotManager.getCurrentBot();

function writeLog() {
    Log.i("함수가 호출되었습니다.");
    return "함수의 실행을 종료합니다.";
    Log.i("로그를 추가로 작성합니다.");
}

function onMessage(msg) {
    msg.reply(writeLog());
}
bot.addListener(Event.MESSAGE, onMessage);

위 코드를 테스트해보면 임의의 메시지를 보냈을 때 카카오톡봇이 '함수의 실행을 종료합니다.'라고 응답하는 것을 알 수 있습니다. 그 후 스크립트 로그를 확인해보세요.

정보

스크립트 로그를 확인하는 방법은 아래와 같습니다.

  1. 메신저봇R 메인화면으로 이동하세요.
  2. 프로젝트를 클릭하고 4번째 버튼을 클릭하세요.

로그를 확인하면 '함수가 호출되었습니다.'만 작성되고 '로그를 추가로 작성합니다.'는 작성되지 않은 것을 확인할 수 있습니다. Log.i("로그를 추가로 작성합니다.");return 다음에 와 무시되었기 때문입니다.

값을 반환하지 않고 함수의 실행을 종료하고자 할 때엔 return을 아래와 같이 사용할 수 있습니다.

function writeLog() {
    Log.i("함수가 호출되었습니다.");
    return;
    Log.i("로그를 추가로 작성합니다.");
}

함수 표현식

함수의 선언은 일종의 표현식으로 접근할 수도 있습니다. 이에 관한 예는 아래와 같습니다.

const add = function add_fn(num1, num2) {
    return num1 + num2;
}

add_fn 함수를 add 상수에 할당했습니다. 이 함수는 아래와 같이 호출할 수 있습니다.

add(3, 8);

콜백 함수

콜백 함수(Callback function)는 함수의 인자로 전달되는 함수입니다. 다양한 방법으로 콜백 함수를 전달할 수 있습니다.

[1, 2, 3, 4, 5].forEach(function callback(e, i) {
    msg.reply(`arr[${i}] = ${e}`);
});
function callback(e, i) {
    msg.reply(`arr[${i}] = ${e}`);
}

[1, 2, 3, 4, 5].forEach(callback);
const fn = function callback(e, i) {
    msg.reply(`arr[${i}] = ${e}`);
}

[1, 2, 3, 4, 5].forEach(fn);

콜백 함수를 필요로 하는 함수를 선언할 수도 있습니다.

function writeLog(callback) {
    Log.i("함수가 호출되었습니다.");
    callback();
}

writeLog(function fn() {
    Log.i("콜백 함수가 호출되었습니다.");
});

/*
Script log:
[i] 함수가 호출되었습니다.
[i] 콜백 함수가 호출되었습니다.
*/
function add(num1, num2, callback) {
    Log.i(`${num1} + ${num2}를 수행합니다.`);
    callback(num1 + num2);
}

add(2, 3, function fn(result) {
    Log.i(`계산 결과는 ${result}입니다.`);
});

/*
Script log:
[i] 2 + 3를 수행합니다.
[i] 계산 결과는 5입니다.
*/

익명 함수

익명 함수는 이름이 없는 함수입니다. 그러므로 선언할 때 함수의 이름을 명명하지 않습니다.

function (매개변수1, 매개변수2, ..., 매개변수N) {
    // 기능의 동작을 위한 코드
    return 반환값;
}

익명 함수는 함수의 이름이 필요하지 않을 때 사용할 수 있습니다. 위의 함수 표현식 예제에서는 함수의 이름과 무관하게 상수의 이름을 사용해 함수를 호출할 수 있습니다. 그러므로 아래와 같이 작성해도 무방합니다.

const add = function (num1, num2) {
    return num1 + num2;
}

익명 함수는 콜백 함수를 전달할 때도 유용합니다.

[1, 2, 3, 4, 5].forEach(function (e, i) {
    msg.reply(`arr[${i}] = ${e}`);
});

화살표 함수

화살표 함수는 익명 함수를 더 간결하게 표현할 수 있는 표현식입니다. 물론 화살표 함수는 익명 함수의 완벽한 대안이 아니나, 기초적인 수준에선 생략하겠습니다.

화살표 함수의 구문은 다음과 같습니다.

(매개변수1, 매개변수2, ..., 매개변수N) => {
    // 기능의 동작을 위한 코드
    return 반환값;
}

화살표 함수는 기본적인 구문 자체로 기존의 익명 함수보다 간결합니다. 하지만, 상황에 따라 더 간결하게 작성할 수 있습니다. 아래는 두 수의 합을 반환하는 익명 함수입니다.

function (num1, num2) {
    return num1 + num2;
}

이를 화살표 함수로 바꾸면 다음과 같으며,

(num1, num2) => {
    return num1 + num2;
}

이를 한 줄로 작성해도 무방합니다.

(num1, num2) => { return num1 + num2; }

충분히 간결하다고 느낄 수 있지만, 더 간결하게 작성할 수 있습니다. 위 함수 내의 코드를 잘 살펴보세요. return 문 외에는 코드가 존재하지 않습니다. 이 경우 중괄호와 return을 생략할 수 있습니다.

(num1, num2) => num1 + num2;

또한, 매개변수가 1개일 경우 매개변수를 감싸는 소괄호를 생략해도 무방합니다.

str => `Argument: ${str}`;

화살표 함수를 사용하면 기존의 함수 표현식을 더 간결하게 표현할 수 있습니다. 이는 실제로 유용하게 쓰이는 표현식입니다.

const add = (num1, num2) => num1 + num2;
[1, 2, 3, 4, 5].forEach((e, i) => {
    msg.reply(`arr[${i}] = ${e}`);
});

실습하기

Q1. 여러분은 특정 문구를 반복해 쓴 값을 반환하는 함수를 구현하고자 합니다. 함수의 정보는 아래와 같습니다.

  • 함수 이름: repeatStr
  • 매개변수
    • n: 반복할 횟수
    • str: 반복하고자 하는 문자열

예를 들어, repeatStr(5, "apple")을 호출하면 문자열 "appleappleappleappleapple"을 반환합니다. 해당 함수를 구현해보세요.

function repeatStr(n, str) {
    let result = "";

    for (let i = 0; i < n; i++) {
        result += str;
    }

    return result;
}

Q2. setTimeout() 함수는 특정 시간이 지난 후 전달받은 콜백 함수를 실행하는 함수입니다. 이 함수는 기본적으로 내장된 함수이므로 여러분이 선언할 필요가 없습니다.
setTimeout() 함수의 첫 번째 인자는 특정 시간이 지난 후 실행할 콜백 함수입니다(콜백 함수의 인자는 없다고 가정합니다). 두 번째 인자는 콜백 함수의 실행을 기다릴 시간(밀리초)입니다.
setTimeout()과 화살표 함수 표기법을 이용해 메시지를 감지하면 5초 후 '메시지 감지!'를 전송하는 코드를 작성해보세요.

const bot = BotManager.getCurrentBot();

function onMessage(msg) {
    setTimeout(() => {
        msg.reply("메시지 감지!");
    }, 5000);
}
bot.addListener(Event.MESSAGE, onMessage);