함수

함수


배경지식

특징

  • 런타임, 즉 프로그램 실행중에 동적으로 생성할 수 있다.
  • 변수에 할당할 수 있고, 다른 변수에 참조를 복사할 수 있으며, 확장가능하고, 몇몇 특별한 경우를 제회하면 삭제할 수 있다.
  • 다른 함수의 인자로 전달할 수 있고, 다른 함수의 반환값이 될수 있다.
  • 자기 자신의 프로퍼티와 매서드를 가질 수 있다.

용어정리

기명함수표현식(named functcion expression) 와 무명함수표현식(unnamed function expression) = 익명함수표현식(anonymous function) 과 함수표현식이 있다.

함수의 이름이 있으면 기명함수, 없으면 무명함수 라고 생각하면 된다.
아래는 예제.

function foo() {} // 함수선언문
var bar = function () {}; // 함수표현식 즉 무명함수표현식
var baz = function  baz () {} // 기명함수표현식

선언문과 표현식: 이름과 호스팅

함수선언문은 전역 유효범위나 다른 함수의 본문 내부, 즉 '프로그램 코드'에서만 사용할 수 있다.
변수나 프로퍼티에 할당할 수 없고, 함수 호출시 인자로 함수를 넘길때도 사용할 수 없다.

함수객체를 매채번수로 전달하거나, 객체리터럴로 매서드를 정의하는 예.

// 함수 표현식을 callMe 함수의 인자로 전달한다
callMe(function () {
    // 이 함수는  무명함수(익명함수) 표현식이다.
});

// 기명함수표현식을 callMe 함수의 인자로 전달한다.
callMe(function me() {
    // 이 함수는 'me' 라는 기명함수 표현식이다.
});

// 함수 표현식을 객체의 프로퍼티로 저장한다.
var myobject = {
    say: function () {
        //  이 함수는 함수 표현식이다.
    }
};

함수 호이스팅

모든 변수는 함수 본문 어느 부분에서 선언(declaration)되더라도 내부적으로 함수의 맨 윗부분으로 끌어올려(hoist)진다.
여기에 함수선언문과 함수푯현식에는 차이점이 있다 잘 보시길 바란다.

// 안티패턴 - 설명을 위해 사용되었음
// 전역 함수
function foo() {
    alert('global foo');
}
function bar() {
    alert('global bar');
}

function hoistMe() {
    console.log(typeof foo); // 'funciton'
    console.log(typeof bar); // 'undefined'

    foo(); // 'local foo'
    bar(); // TypeError

    // 함수선언문:
    // 변수 'foo'와 정의돈 함수 모두 호이스팅된다.
    function foo() {
        alert('local foo');
    }

    // 함수표현식
    // 변수 'bar'는 호이스팅 되지만 정의된 함수는 호이스팅되지 않는다.
    var bar = function () {
        alert('local bar');
    };
}
hoistMe();

hoistMe() 함수 내에서 foo와 bar를 정의하면 실제 변수를 정의한 위치와 상관없이 끌어올려져 전역 변수인 goo, bar를 덮어쓰게 된다.
그런데 지역변수 foo() 는 나중에 정의되어도 상단으로 호이스팅되어 정상동작하는 반면, bar()의 정의는 호이스팅되지 않고 선언문만 호이스팅 된다.
때문에 bar()의 정의가 나오기전까지는 undefined 상태이고, 함수로도 사용할 수 없다.
또한 선언문 자체는 호이스팅되었기 때문에 유효번위 체인 내에서 전역 bar()도 보이지 않는다.

출처 : JavaScript Patterns