[JS] 자바스크립트의 함수 선언? 차이가 알고 싶다!

Wooki·2023년 4월 20일
0

JavaScript

목록 보기
2/7

자바스크립트로 개발을 하다 보면 함수를 선언할 때 변수에 함수를 바로 할당 하는 경우와 function 예약어를 이용해 선언 할 때가 있다. 이 두경우의 차이점에 대해서 문득 궁금해졌고 어떤 차이가 있는지 알아보려고 한다.

함수 선언식과 함수 표현식?

JavaScript에서 함수를 사용할때 두가지 방식으로 사용할 수 있다.

function (함수 선언식)

function function1 () {      
  console.log("function1");
}

이처럼 function 예약어를 사용해서 사용하는 것을 함수 선언식 이라고 한다.
javascript 말고도 일반적인 프로그래밍 언어들에서 위 방식을 이용해 함수를 선언한다.

변수에 할당 (함수 표현식)

var function2 = function funcA () {   // 함수의 이름을 정할수도
  console.log("function2");
}

var function3 = function () { // 함수에 이름을 주지 않고 익명 함수로 쓸수도 있다.
  console.log("function3");
}

이처럼 함수의 이름을 생략하고 바로 변수에 함수를 할당하는 방식을 함수 표현식 이라고 한다.


표현식과 선언식 그 차이가 뭘까?

javaScript Docs의 함수 선언식, 표현식에 대한 글을 찾아보면 호이스팅에 대한 차이가 있다.

Function declaration hoisting (함수 선언 호이스팅)

Function declarations in JavaScript are hoisted to the top of the enclosing function or global scope. You can use the function before you declared it:
(자바스크립트에서 함수 선언은 그 선언을 둘러싼 함수의 최상부나 전역 범위(global scope)로 끌어올려집니다.)

함수 선언식의 경우

hoisted(); // logs "foo"

function hoisted() {
  console.log("foo");
}

함수 선언식으로 함수를 선언하게 되면 호이스팅이 발생해서 함수가 선언되기 전에 해당 함수를 사용할 수 있지만,

함수 표현식의 경우

notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
   console.log("bar");
};

이처럼 함수 표현식으로 함수를 선언하게 되면 함수에 대한 호이스팅이 발생하지 않아 TypeError가 발생한다.

왜 호이스팅이 일어나지 않는 것일까?

JavaScript에서 호이스팅이란, 변수의 선언과 초기화를 분리한 후 선언만 스코프의 최상단 으로 옮기는 것이기 때문이다.

notHoisted(); TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("catfish");
};

// 선언부 :  var notHoisted
// 변수의 초기화 : function () { console.log("catfish"); }

즉, 위 코드는 호이스팅 시 함수의 선언부인 var notHoisted 부분만 끌어올려지게 될 것이고.

var notHoisted = undefined;
// var로 선언한 변수는 호이스팅 시 undefined로 초기화된다.
// const나 let으로 선언한 변수의 경우 undefined로 초기화하지 않는다.

nonHoisted(); // TypeError: notHoisted is not a function
// 이 시점에서 nonHoisted는 undefined 값을 가지는 변수일 뿐이다. 

notHoisted = function () {
  console.log("catfish);
}         

실제로는 이렇게 동작하게 된다. notHoisted 변수 자체는 사용할 수 있지만 해당 변수는 아직 함수가 할당되기 전이므로 함수를 할당하기 전까지는 해당 함수를 호출할 수 없게 된다.


함수 표현식의 용도

호이스팅에 영향을 받지 않는다는 특징 이외에도, 함수 표현식은 클로져 사용 시나, 다른 함수의 인자로 함수를 전달할 때 유용하게 사용할 수 있다는 특징이 있다.

코드의 가독성

호이스팅에 영향을 받지 않기 때문에 선언하기 전에 함수를 호출할 수 없어서 코드의 가독성을 높일 수 있다.

함수의 이름을 마음대로 정할수 있어서 디버깅에 유리하다

function alertLog () { // 선언식의 경우 함수의 이름이 alertLog
  alert("log");
}

---
  
// 변수명이 alertLog이고 함수명은 examLog가 된다.
var alertLog = function examLog () {
  alert("log");
}

클로저 사용 시 또는 함수의 인자로 전달

함수 표현식은 클로저를 구현할 때나, 함수의 인자로 전달할 때 유용하게 쓰일 수 있다.

클로저

function myFunc() { // 함수 선언식
  var count = 0;
  return function () { // 함수 표현식
    console.log(count);
  }
}

함수의 인자

var element1 = document.getElementById("element1");

element1.onclick = function () { // 함수 표현식
  console.log("element");
}

느낀점

뭔가 비슷한거 같으면서 미묘하게 다른.. 이제 화살표 함수, 익명 함수, 명명 함수(?), 즉시 실행 함수 등 더 궁금한게 많아 졌다.
특히 화살표 함수와 일반 함수의 차이가 뭔지 전부터 궁금했다.
다음 포스트는 화살표 함수로 정했다!

참고

MDN 함수 선언식
MDN 함수 표현식

profile
웹 개발자

0개의 댓글