본문 바로가기

함수 표현식과 함수 선언식의 차이점 본문

STUDY/Javascript N Jquery

함수 표현식과 함수 선언식의 차이점

Publee 2019. 3. 5. 17:47

 함수선언식(Function Declarations) 이란? 


일반적인 프로그래밍 언어에서의 함수 선언과 비슷한 형식입니다.

function 함수명() {
  // 내용
};


//예시
function abc() {
  return 'abcdefghijklmnopqrstuvwxyz'
}

abc(); // 'abcdefghijklmnopqrstuvwxyz'


 함수표현식(Function Expressions)이란 ? 

유연한 자바스크립트 언어의 특징을 활용한 선언 방식


var 함수명 = function () {
  // 내용
}


//예시
var abc = function () {
  return 'abcdefghijklmnopqrstuvwxyz'
}

abc(); // 'abcdefghijklmnopqrstuvwxyz'


 함수 선언식과 표현식의 차이점은? 

 함수 선언식은 호이스팅에 영향을 받지만, 함수 표현식은 호이스팅에 영향을 받지 않습니다. 


예를 들면,

// 실행전
aaa();
bbb();

function aaa() {
  return 'aaa';
}

var bbb = function () {
  return 'bbb';
};


호이스팅에 의해 자바스크립트 해석기는 아래와 같이 해석합니다.

// 실행시
function aaa() {
  return 'aaa';
}

var bbb;

aaa(); // 'aaa'
bbb(); // Uncaught TypeError: bbb is not a function

bbb = function () {
  return 'bbb';
};

함수 표현식 bbb 에서 var 도 호이스팅이 적용되어 위치가 상단으로 끌어올려졌습니다.

하지만 실제 bbb에 할당된 function은 호출된 이후에 선언되므로, bbb는 함수로 인식되지 않고 변수로 인식하게 됩니다



 그렇다면 함수 표현식의 장점은 ? 

'함수 표현식은 호이스팅에 영향을 받지 않는다'는 특징 이외에도 함수 선언식 보다 유용하게 쓰이는 경우가 있습니다.


하나는 클로저로서의 사용

두번째는 콜백으로서의 사용 (다름 함수의 인자로 넘길 수 있습니다.)



 함수 표현식으로 클로저 생성하기 

 클로저는 함수를 실행하기 전에 해당 함수에 변수를 넘기고 싶을 때 사용합니다. 


예제를 살펴보면,

<ul class="tab">
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

<script>
  function tabHandler(index) {
    return function tabClickEvent(event) {
      // 위에 tabHandler 함수의 index 인자를 여기서 접근이 가능하다.
      console.log(index); // 탭을 클릭시 해당 탭의 index 값을 표시
    }
  }

  var tabs = document.querySelectorAll('.tab li');
  var i;

  for (i = 0; i < tabs.length; i += 1) {
      tabs[i].onclick = tabsHandler(i);
  }
</script>


위 예제는 모든 .tab 요소에 클릭이벤트를 추가하는 예제입니다.

주목할 점은 클로저를 이용해  tabClickEvent() 에서  tabsHandler() 의 인자의 값을 접근할 수 있다는 점 입니다.


for 반복문의 실행이 끝난 후, 사용자가 tab을 클릭했을 때  tabClickEvent() 가 실행됩니다.

만약 클로저를 쓰지 않는다면 모든 tab의 index 값은 for 반복문의 마지막 값인 tabs.length와 같습니다.





 클로저를 쓰지 않은 예제를 보면 

var tabs= document.querySelectorAll('.tab li');
var i;

for (i = 0; i < tabs.length; i +=1) {
  tabs[i].onclick= function (event) {
    console.log(i); // 어느탭을 클릭해도 tabs.length의 최종 값 출력
  };
}


문제점을 더 파악하기 쉽게 for 문 안의 function() 을 밖으로 꺼내서 확인해보면

var tabs = document.querySelectorAll('.tab li');
var i;
var thisIndex = function (event) {
  console.log(i); // 최종값
};

for (i = 0; i < tabs.length; i += 1) {
  tabs[i].onclick = thisIndex;
}


thisIndex가 실행되는 시점은 이미 for문의 실행이 끝난 시점입니다.

따라서, 어느 탭을 눌러도 for 문의 최종 값이 찍히게 됩니다.


그래서 클로저를 적용하여 for 문이 수행될 때 각 i값을 tabsHandler()에 넘기고, 클로저인 tabClickEvent() 에서 tabsHandler()의 인자 값 index 를 접근할 수 있게 됩니다.


즉, 우리가 원하는 각 탭의 index를 접근할 수 있게 됩니다.



함수 표현식을 다른 함수의 인자 값으로 넘기기

var msg = function () {
  console.log('Hello World');
}

$(document).ready(msg);


함수 표현식을 임시 변수에 넣지 않고도 아래와 같이 콜백함수로 사용할 수 있습니다.

$(document).ready(function () {
  console.log('Hello World');
});


※ 콜백함수란 다른 함수의 인자로 전달된 함수를 의미합니다.




출처: https://joshua1988.github.io/web-development/javascript/function-expressions-vs-declarations/

Comments