여섯 번째 Deno(JavaScript) 기초 강의에서는 콜백, 익명 함수에 대해 설명하겠습니다.

함수 강의를 분리해서 작성하다보니 부득이 콜백 함수와 익명 함수를 하나의 글에 작성하게 되었습니다. 콜백 함수와 익명 함수를 하나의 글에서 설명하는 것이 콜백 함수와 익명 함수가 서로 비슷한 개념인 것으로 설명하려는 의도는 아니라는 점을 이해해 주십시오.


콜백 함수

앞서 배워온 강의에서는 함수가 매개변수를 요구할 수 있고 함수 또한 객체, 자료 중 하나라고 설명했었습니다. 그러면 함수의 인자에 함수를 제출할 수 있다는 사실을 이해하실 수 있을 것으로 생각됩니다.

함수의 인자에 함수를 제출한다는 개념이 생소하신가요? 다음의 예제를 살펴보세요.

function person(name, gender, age) {
    this.name = name;
    this.gender = gender;
    this.age = age;
}

person.prototype.eat = function(foodName, processAfterEating) {
    console.log(foodName + '을 먹었습니다!');
    processAfterEating();
}

const gildong = new person('홍길동', '남성', 5);

function metabolismForApple() {
    // 소화 과정에 대한 전문 지식없이 간단히 작성했습니다.
    console.log('사과가 식도로 왔습니다.');
    console.log('사과가 위로 왔습니다.');
    console.log('사과가 장으로 왔습니다.');
    console.log('소화 완료!');
}

gildong.eat('사과', metabolismForApple);

위 코드를 요약하면 다음과 같습니다.

  1. person 함수(객체)를 생성합니다. person이 선언될 때 name(사람 이름), gender(성별), age(연령)를 매개변수로 받고 생성된 객체 안에 각각 저장합니다.
  2. person 객체의 프로토타입 함수 eat을 생성합니다. 이 함수가 호출될 때 foodName(음식 이름), processAfterEating(음식을 먹고 난 후 과정)을 매개변수로 받고 음식 이름을 출력한 다음 processAfterEating을 실행합니다.
  3. 새로운 person 객체를 gildong에 저장합니다.
  4. metabolismForApple 함수를 생성합니다. 이 함수가 호출될 때 아무런 매개변수도 받지 않고 소화 과정을 간단히 출력합니다.
  5. gildong에 대하여 eat 함수에 사과와 (4)에서 생성한 metabolismForApple 함수를 인자로 제출합니다.

위 예제 저 코드에서 무언가 개선되어야 한다는 생각이 드시나요? “metabolismForApple 함수는 한 번만 실행되는데 왜 메모리에 저장할까요?” 라는 의문을 제기할 수 있어야 합니다. 앞서 우리는 다음과 같이 함수를 선언할 수도 있다고 배웠었습니다.

const sampleFunction = function() {
    // ...
}

이 사실을 응용하면 다음과 같이 코드를 정리할 수 있습니다.

function person(name, gender, age) {
    this.name = name;
    this.gender = gender;
    this.age = age;
}

person.prototype.eat = function(foodName, processAfterEating) {
    console.log(foodName + '을 먹었습니다!');
    processAfterEating();
}

const gildong = new person('홍길동', '남성', 5);

gildong.eat('사과', function() {
    // 소화 과정에 대한 전문 지식없이 간단히 작성했습니다.
    console.log('사과가 식도로 왔습니다.');
    console.log('사과가 위로 왔습니다.');
    console.log('사과가 장으로 왔습니다.');
    console.log('소화 완료!');
});

위와 같이 정리된 코드의 맨 마지막 부분에서 보여드린 함수를 인자로 제출하는 방법은 콜백 함수로 가장 많이 사용됩니다. 앞으로 콜백 함수를 더 적극적으로 활용할 예정이니 이런 개념이 있다는 사실만 먼저 익혀두시기 바랍니다.


익명 함수

지난 강의에서는 함수를 이용한 객체 지향적 코드 설계 방법에 대해 간단히 알아봤었습니다. 함수에는 객체로서의 기능이 포함되어 있다는 사실을 알 수 있으셨을 거라고 생각합니다. 익명 함수는 객체의 기능이 제외된 함수입니다. 사실상 코드의 묶음이라고 설명할 수 있겠습니다.

익명 함수의 형태

// 익명 함수
const sendMessage = (message) => {
    console.log(message);
}
// 일반 함수
const sendMessage = function(message) {
    console.log(message);
}

익명 함수의 구조를 더 쉽게 이해할 수 있도록 같은 기능을 하는 일반 함수와 익명 함수를 모두 작성하였습니다.

익명 함수는 일반 함수와 다르게 함수라는 표기(function)를 사용하지 않습니다. 매개변수를 선언한 다음 화살표(=>)로 코드 블럭({ })을 가리키는 형태입니다. 코드의 형태에서 보이는 것처럼 익명 함수에는 화살표가 사용됩니다. 이러한 형태를 보고 익명 함수를 ‘화살표 함수’라고 부르는 사람들도 있습니다.

익명 함수를 사용해야 하는 경우

언제 익명 함수를 사용해야 하는지 판단하는 방법은 간단합니다. 객체(this)가 필요하지 않거나 객체가 필요하지 않으면서 상위 객체에 엑세스해야 하는 함수가 필요한 때입니다. 익명 함수는 구조적으로 일반 함수 대비 컴퓨팅(연산)에 덜 부담을 줍니다.

아직 배우지 않았지만 일반 함수에는 Prototype이라는 개념이 존재합니다. 일단 함수가 일반 함수로 작성되면 컴퓨터는 그 개념을 구현하기 위해 연산을 시행합니다. 반면에 익명 함수는 단순한 코드 블럭의 개념이므로 일반 함수보다 연산을 덜 할 수 밖에 없습니다.

객체가 필요하지 않으면서 상위 객체에 엑세스해야 함에도 불구하고 상위 객체를 매개변수로 제출할 것을 요구하도록 코드를 작성하면 상위 객체가 메모리 상에서 복제되므로 메모리를 더 많이 사용하게 됩니다.

배운 콜백 함수를 사용하는 경우에는 익명 함수를 사용해도 될 확률이 높습니다. 콜백 함수 안에서 this가 필요하지 않으면 익명 함수를 사용해도 됩니다.

이 내용이 이해되지 않으셔도 괜찮습니다. 설명하지 않으면 강의에 문제가 되어서 부득이 설명을 포함한 것일 뿐입니다.


다음 강의 예고

다음 강의에서는 JavaScript ES6에서의 조건문에 관하여 간단히 알아보겠습니다.

질문이 있으시면 아래 댓글을 이용해 주세요. 감사합니다.