JavaScript/Vanilla JS

내부함수와 자기 호출 함수, 콜백함수

유혁스쿨 2022. 1. 17. 16:25
728x90
반응형

내부함수

내부함수는 프로그램의 규모가 커질수록 다른사람과 함께 프로그램을 개발하게 되는데 이때 발생하는 여러가지 충돌을 막기위한 방법중 하나이다.

다음과 같은 형태로 구현한다.

function 외부함수 () {
    function 내부함수1() {
        //함수 코드
    }
    function 내부함수2() {
        //함수 코드
    }
    //함수 코드
}

 

 

피타고라스를 정리하는 함수 pythagoras()를 만들어 내부함수를 구현해본다.

function pythagoras(width,height) {
    return Math.sqrt(width*width + height*height);
}

 

숫자를 제곱하는 부분은 피타고라스에서 자주 사용되는 내용이므로 별도의 square()함수로 구현한다.

function square(x) {
    return x*x;
}

function pythagoras(width,height){
    return Math.sqrt(square(width) + square(height));
}

 

만약 규모가 큰 웹 애플리케이션을 만들 때 같은 팀 구성원이 square의 다른 뜻인 "직각"으로 착각하여 같은 이름으로 직각 삼각형인지 확인하는 함수를 만들었다면 문제가 발생하게된다.

/*남궁 사원이 만든 square함수*/
function square(x) { //제곱근을 구하는 함수
    return x*x;
}

function pythagoras(width,height){
    return Math.sqrt(square(width) + square(height));
}

alert(pythagoras(3,4));

/*유 사원이 만든 square함수*/
function square(width, height, hypotenuse) {//삼각형이 직각인지 확인하는 함수
    if (width * width + height * height == hypotenus * hypotenuse) {
        return true;
    }else {
        return false;
    }
}

남궁 사원의 square() 함수는 유 사원의 square()함수에 덮어 씌어진다.

따라서 pythagoras()함수 내부에서는 유 사원의 square() 함수를 사용하게 된다.

 

해결방안은 두 사원이 사전에 협의하여 함수이름을 서로 다른 이름으로 사용하거나, 가변 인자 함수로 같은 이름이어도 서로 다른 기능을 수행하게 하여 충돌을 예방할 수 있다.

그렇지 않다면 원하지 않는 결과가 발생하게된다.

이와 같은 상황에서 내부함수를 사용하면 간단하게 함수 이름 충돌을 막을 수 있다.

function pythagoras(width,height){
    function square(x) { //제곱근을 구하는 함수
        return x*x;
    }
    return Math.sqrt(square(width) + square(height));
}

위와 같이 내부 함수로 구현하면 되지만 한가지 주의할 점이 있다.

내부 함수는 내부 함수가 포함되는 함수에서만 사용이 가능하다.

pythagoras() 함수 외부에서 square()함수를 사용할 수 없다. 이것은 지역변수 개념과도 같다.

 

 

자기호출 함수

자기호출 함수는 다음과 같은 형태이며 함수를 생성하자마자 호출한다.

// 타입1
(function () {
    //코드
    //코드
    //코드
})();

// 타입2
(function () {
    //코드
    //코드
    //코드
}());

// 타입3
!function () {
    //코드
    //코드
    //코드
}();

보통은 다른 개발자에게 영향을 주지 않게끔 사용한다. (익명함수로 구성되어있다.)

function(){}을 ()괄호로 한번 묶어주고 그 옆에 바로 ()를 한번 더 선언하면 함수가 선언되자마자 따로 호출문 없이 실행된다.

이전 포스팅에서 설명했듯이 함수는 호출시 함수명 바로 옆에 (); 괄호를 열고닫음으로써 함수를 호출하여 함수내부의 코드를 실행한다.

따라서 function(){} 선언 자체를 (괄호)로 묶는 순간 자료형과 같은 상태로 볼 수 있으며 함수명(); 에서 함수명이라고 볼 수 있다.

따라서 function(){} 선언 자체를 (괄호)로 묶는 문법은 익명함수에서 호출할 함수 명을 대체하는것으로 볼 수 있다.
(즉, 함수명(); 에서 '함수명' 에 해당한다고 볼 수 있다. )

 

또한 아래 코드와 같이 매개변수를 넘길수도 있다.

(function (msg) {
console.log(msg);
}("hello!"));

(function (msg) {
console.log(msg);
})("hello!");

!function (msg) {
console.log(msg);
}("hello!");

함수 선언부의 ()에 argument로 사용될 변수명을 입력해 준 뒤, 마지막 괄호에서 호출할때 넘길 매개값을 작성하면 함수 블록 내부에서 해당 값을 매개변수로 사용할 수 있게 된다.

 

API를 보다가 많이 마주칠 수 있으므로 자기호출함수의 형태를 꼭 기억하자!

 

콜백함수

자바스크립트 에서는 함수도 하나의 자료형이므로 매개변수로 전달할 수 있다.

이렇게 매개변수로 전달하는 함수를 콜백함수 라고 부른다.

다른 프로그래밍 언어에서는 찾아보기 힘든 개념이다.

 

function callTenTimes(callback) {
    for (var i = 0; i < 10; i++) {
        callback();
    }
}
/*
function callback () {
    alert('함수 호출');
}
*/
var callback = function() {
    alert('함수 호출');
}
callTenTimes(callback);

 

callback함수를 매개변수로 받아 10번 호출하는 함수 로직이다.

코드를 실행하면 '함수 호출' 이라는 문자열을 담은 alert창을 10회 출력한다.

 

 

익명 콜백함수

function callTenTimes(callback) {
    for (var i = 0; i < 10; i++) {
        callback();
    }
}
callTenTimes(function() {
    alert('함수 호출');
});

콜백함수는 익명함수로 바로 선언하여 사용하는 경우가 많다.

위 코드와 같이 callTenTimes () 함수의 매개변수로 익명함수를 곧바로 입력할 수도 있다.

 

함수를 매개변수로 전달하는 것은 분명한 이유가 있다.

이전 포스팅에서 예를들었던것과 같이 매개변수로 전달받은 콜백 함수를 반복문을 통해 여러번 실행할 수 있고, 이러한 형태는 이벤트에서 주로 쓰이게된다.

 

728x90
반응형