자바스크립트에서 함수를 생성하는 방법은 여러가지가 있습니다.


방법 하나.

function a(str){
   alert(str);
}

방법 둘.

var a = function(str){
   alert(str);
}


방법 셋.

var a = new Function('str', 'alert(str)');

위의 세가지 방법 모두 아래와 같은 방법으로 호출 할 수 있습니다.


a('hello');


new 키워드를 사용해서 함수 객체를 생성하는 세번째 방법은 문자열로 함수 body를 작성해야 하기때문에 불편하죠.

그래서 거의 사용되지 않는 방법 일겁니다.

나머지 두가지 방법은 자주 사용하는 것인데, 이 둘간의 차이가 무엇일까요?


첫번째 방법은 함수 선언부에서 함수의 이름을 지정하고, 두번째 방법은 함수를 변수에 할당하고 있습니다.

자바스크립트의 함수는 일급객체로 변수에 저장하고, 함수의 반환값이나 파라미터로 사용될 수 있기 때문이죠.

그래서 웬지 좀 더 있어보이는것 같아서 두번째 방법을 쓰기도 합니다.


자 그럼 이 두가지 함수 생성방법의 차이점을 알아 볼까요?


두 가지 방법을 각각 사용해서 두개의 함수를 만들고 호출해 보겠습니다.



function a(str){
    alert(str);
}

var b = function(str){
    alert(str);
}

a();
b();
결과는 두개의 함수가 정상적으로 호출됩니다. 이제 함수호출하는 코드를 위쪽으로 자리를 옮겨 보겠습니다.
a();
b();

function a(str){
    alert(str);
}

var b = function(str){
    alert(str);
}
결과는 a()는 정상적으로 호출되었으나 b()를 호출 하는 곳에서 에러를 발생합니다.
에러 메세지는 "b is not a function" 라고 나옵니다.


두개의 함수 모두 호출부 보다 아래에 선언부를 두었는데, 
a()는 제대로 호출이 되는 반면 b()는 이런 오류가 나는 것이 가장 큰 차이점 입니다.


함수를 만들지도 않고 호출하는데 호출이 되는 놈이 더 이상해 보이나요?

그리고, 오류 메세지도 조금 이상하지요? 

아래 코드 처럼  만들지도 않은 변수를 접근하는 경우 나타나는 오류 메세지는 "i is not defined"입니다.


<script>
  alert(i);
</script>


자바스크립트는 함수와 변수를 선언하는데 var, function을 사용합니다.

이렇게 선언한 함수와 변수는 참조하는 코드가 그 보다 우선해서 나타나도

다시말해 사용하는 것보다 선언하는 코드가 아래 쪽에 나타나도

마치 코드의 맨윗부분에 선언한것처럼 동작합니다.

이런것을 호이스팅(hoisting)이라고 합니다.


그래서 첫번째 함수는 제대로 호출이 되고 두번째 함수는 변수 b만 위로 끌어 올려져서 변수까지만 접근이 됩니다.

다만, 그 변수에 할당된 함수리터럴은 할당되지 않은 상태이기 때문에 

'not defined'가 아닌 'not a function' 에러 메세지가 나타나게 됩니다.


또다른 차이점으로 a.name 프로퍼티에는 'a'가 자동으로 할당되어 집니다.


함수의 선언은 아무래도 가독성을 위해서라도 코드의 상단에 하는 것이 좋겠지요.

하지만, 경우에 따라 선언부가 아래쪽에 위치해야 하는 경우도 생기게 되는데,

이때 이런 메카니즘을 이해하는 것은 꼭 필요한 것이겠지요.



출처: http://blog.xcoda.net/65 [악보쓰는 프로그래머]