[JavaScript] 함수 선언식과 함수 표현식

GonnabeAlright·2021년 11월 25일
0
post-thumbnail

함수 선언식

// function statement
function sum() {
 	return 10 + 20; 
}

함수 표현식

// function expression (; 존재)
var sum = function () {
 	return 10 + 20; 
};

수 표현식이 변수에 저장되면, 변수는 함수처럼 사용 가능해진다. 변수에 저장된 함수는 함수명이 필요없으며, 변수 이름을 통하여 호출된다.

함수 표현식

alert(foo());			// Error
var foo = function () {
 	return 5; 
}

함수 선언식

alert(foo());			// 정상 동작

function foo() {
  	return 5;
}

함수 선언식은 코드가 실행되기 전에 로드되지만, 함수 표현식은 인터프리터가 해당 코드 줄에 도달할 때만 로드된다.

함수 선언식은 var문과 유사하게 호이스팅된다. 반면, 함수 표현식은 호이스팅되지 않으므로 정의된 범위에서 로컬 변수의 복사본을 유지할 수 있다.

일반적으로 함수 선언식과 함수 표현식은 함께 사용할 수는 있지만, 함수 표현식은 함수 이름이 필요없기에 가독성이 더 높은 장점이 있다.

함수 표현식의 장점

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

  • 클로져로 사용
  • 콜백으로 사용 (다른 함수의 인자로 넘길 수 있음)

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

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

function tabsHandler(index) {
 	return function tabClickEvent(event) {
      	// 바깥 함수인 tabsHandler()의 index 인자를 여기서 접근할 수 있다.      	// 탭을 클릭할 때마다 해당 탭의 index 값을 표시
      	console.log(index);
    };
}

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

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

위 예제는 모든 .tab 요소에 클릭 이벤트를 추가하는 예제다. 주목할 점은 클로져를 이용해 tabClickEvent()에서 바깥 함수 tabsHandler()의 인자 값 index를 접근했다는 점이다.

function tabsHandler(index) {
 	return function tabClickEvent(event) {
      console.log(index);
    };
}

for 반복문의 실행이 끝난 후, 사용자가 tab을 클릭했을 때 tabClickEvent()가 실행된다. 만약 클로져를 쓰지 않았다면 모든 tab의 index 값이 for 반복문의 마지막 값인 tabs.length와 같다.

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

클로져를 쓰지 않은 예제를 보자.

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

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

이 문제점을 해결하기 위해 클로져를 적용하면 for 반복문이 수행될 때 각 i값을 tabsHandler()에 넘기고, 클로져인 tabClickEvent()에서 tabsHandler()의 인자값 index를 접근할 수 있게 된다. 따라서, 우리가 원하는 각 탭의 index를 접근할 수 있다.

function tabsHandler(index) {
	return function tabClickEvent(evt) {
      	// 바깥 함수인 tabsHandler의 index 인자를 여기서 접근할 수 있다.
      	// 탭을 클릭할 때마다 해당 탭의 index 값을 표시
      	console.log(index);
    };
}

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

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

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

함수 표현식은 일반적으로 임시 변수에 저장하여 사용한다.

// doSth이라는 임시 변수를 사용
var doSth = function () {
  	// ...
};

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

$(document).ready(function () {
  	console.log('An anonymous function');
});

jQuery를 사용할 때 많이 보던 문법으로 위와 아래의 코드 결과는 같다.

var logMessage = function() {
  	console.log('An anonymous function');
};

$(document).ready(logMessage);		// 'An anonymous function'

자바스크립트 내장 API인 forEach()를 사용할 때도 콜백함수를 사용할 수 있다.

var arr = ["a", "b", "c"];
arr.forEach(function () {
  	// ...
});

함수 표현식이 선언식에 비해 가지는 장점이 많지만, 결국에는 이러한 차이점을 인지한 상태에서 일관된 코딩 컨벤션으로 코드를 작성하는 게 중요합니다.

  • 코딩컨벤션 : 나 자신 외에 다른 사람들도 내가 작성한 코드를 보고 쉽고 빠르게 이해할 수 있도록 작성하는 작성 표준

0개의 댓글