4. 함수와 프로토타입 체이닝 #3 함수의 다양한 형태

2021. 7. 26. 16:20JavaScript/basic

본 글은 인사이드 자바스크립트 도서의 내용을 복습하기 위해 작성된 글입니다.

4.3 함수의 다양한 형태

  • 콜백 함수(CallBack Function)
  • 즉시 실행 함수(Immediate Function)
  • 내부 함수(Inner Function)
  • 함수를 리턴하는 함수

4.3.1 콜백 함수(CallBack Function)

콜백함수는 코드를 통해 명시적으로 호출하는 함수가 아니라, 개발자는 단지 함수를 등록하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출되는 함수를 말한다. 또한, 특정 함수의 인자로 넘겨서, 코드 내부에서 호출되는 함수 또한 콜백 함수가 될 수 있다.

 

대표적인 콜백 함수의 사용 예가 자바스크립트에서의 이벤트 핸들러 처리이다.

 

자바스크립트의 이벤트 처리와 콜백 함수

window.onload 이벤트 핸들러 예제 코드

// window.onload 이벤트 핸들러에 콜백함수 설정
window.onload = function(){
    alert("this is the callback function");
}

웹 페이지가 로드됐을 때 경고창을 띄워 주는 간단한 예제이다. window.onload는 이벤트 핸들러로서, 웹 페이지의 로딩이 끝나는 시점에 load 이벤트가 발생하면 실행된다. 예제에서는 window.onload 이벤트 핸들러를 익명함수로 연결했다. 따라서 익명 함수가 콜백 함수로 등록된 것이다.

 

4.3.2 즉시 실행 함수

즉시 실행 함수(Immediate Function)란?

함수를 정의함과 동시에 바로 실행하는 함수를 즉시 실행 함수라 한다.

 

즉시 실행 함수 예제

// 즉시 실행 함수 예제 코드
(function (name){
    console.log("this is the immediate function -> "  + name);
})("foo");  // this is the immdeidate function -> foo

 

즉시 실행 함수 생성 방법

  1. 함수를 괄호로 둘러싼다.
  2. 함수가 바로 호출될 수 있게 () 괄호 쌍을 추가한다.

즉시 실행 함수 특징 및 용도

  1. 즉시 실행 함수의 경우 같은 함수를 다시 호출할 수 없다.
  2. 즉시 실행 함수의 특징을 이용하여 최초 한번의 실행만을 필요로 하는 초기화 코드 부분 등에 사용된다.
  3. 즉시 실행 함수는 jQuery와 같은 자바스크립트 라이브러리나 프레임워크 소스들에 사용된다.

jQuery에서 사용된 즉시 실행 함수

(function(window, undefined){
    // ...
})(window);

 

4.3.3 내부 함수

내부 함수(Inner Function)이란 무엇인가?

함수 코드 내부에 다시 함수 정의하는 함수를 내부 함수라고 한다. 내부 함수는 자바스크립트의 기능을 보다 강력하게 해주는 클로저를 생성하거나 부모 함수 코드에서 외부에서의 접근을 막고 독립적인 헬퍼 함수를 구현하는 용도 등으로 사용한다.

 

내부 함수 예제 코드

// parent() 함수 정의
function parent(){
    let a = 100;
    let b = 200;

    // child() 내부 함수 정의
    function child(){
        let b = 300;

        console.log(a);
        console.log(b);
    }
    child();
}

parent();   // 100 300
child();    // uncaught ReferenceError : childi s not defined

위 코드에서 parent() 함수 내부에 child() 함수를 정의했다. 따라서 child() 함수는 내부 함수이다. parent() 함수 호출시 parent() 함수 내부의 마지막에 child() 함수를 호출하였고 child() 함수를 호출하면서 a 변수를 참조하였는데 a 변수는 child() 함수 내부에 없으므로 부모 함수인 parent() 함수의 변수 a를 참조하여 100을 출력하였다. 그리고 b 변수는 child() 함수와 parent() 함수 두 곳에 선언 되어 있는데 제일 가까운 child() 함수의 변수 b를 참조하여 300을 출력하였다. 그리고 외부에서 child() 함수 호출시 내부 함수이기 때문에 호출이 불가능하였다.

 

위의 설명을 정리하면 내부 함수에서는 자신을 둘러싼 부모 함수의 변수에 접근이 가능하다. 이는 자바스크립트의 스코프 체이닝 때문이다. 스코프 체이닝과 관련해서는 5장에서 설명될 예정이다.

 

내부 함수 예제 코드 도식화

위 그림에서 함수를 둘러싸고 있는 박스 부분이 바로 함수 스코프를 의미한다. 기본적으로 함수 스코프 밖에서는 함수 스코프 안에 선언된 모든 변수나 함수에 접근이 불가능하다.

 

그리고 자바스크립트 스코프 체이닝 때문에, 함수 내부에서는 함수 밖에서 선언된 변수나 함수의 접근이 가능하다. 하지만 함수 외부에서도 특정 함수 스코프 안에 선언된 내부 함수를 호출 할 수 있다. 가령, 부모 함수에서 내부 함수를 외부로 리턴하면, 부모 함수 밖에서도 내부 함수를 호출하는 것이 가능하다.

 

함수 스코프 외부에서 내부 함수를 호출하는 예제 코드

function parent(){
    let a = 100;

    // child() 내부 함수
    let child = function(){
        console.log(a);
    }

    // child() 함수 반환
    return child;
}

let inner = parent();
inner();    // 100

외부에서 내부 함수를 호출하기 위해서 내부 함수를 함수 표현식으로 정의하고, child 함수 변수를 리턴한다. 그리고 외부에서 부모(parent) 함수를 호출함으로써 내부 함수를 반환받아 호출한다. 때문에 inner 변수에 함수 호출 연산자 ()를 붙여 함수 호출 구문을 만들면, parent() 함수 스코프 밖에서도 내부 함수 child()가 호출된다. 호출하는 내부 함수(child)에는 a 변수가 정의되어 있지 않아, 스코프 체이닝으로 부모 함수에 a 변수가 정의되어 있는지 확인하게 되고, a가 정의되어 있으면 그 값(100)이 그대로 출력된다.

 

클로저(Clousure)란 무엇인가?

실행이 끝난 parent()와 같은 부모 함수 스코프의 변수를 참조하는 inner()와 같은 함수를 클로저라고 한다.

 

4.3.4 함수를 리턴하는 함수

자바스크립에서는 함수도 객체이기 때문에 함수 자체를 리턴할 수 있다. 이러한 특징은 다양한 활용이 가능해진다. 함수를 호출함과 동시에 다른 함수로 바꾸거나, 자기 자신을 재정의하는 함수를 구현할 수 있다.

 

자신을 재정의하는 함수 예제 코드

// self() 함수
let self = function(){
    console.log("a");

    return function(){
        console.log("b");
    }
}
self = self();  // a
self();         // b

 

References

인사이드 자바스크립트, 송형주 저