본문 바로가기

WEB/HTML CSS JS

[JS] 함수 선언문과 함수 표현식

Function Declaration

  • 함수 선언문 방식은 function 정의부만 존재하고 별도의 할당 명령이 없다.
function name(parameters) {
  /* expression */
}

 

  • 함수 내에서 선언된 지역변수는, 동일한 변수명을 가진 전역변수를 가린다.
  • 반드시 함수명이 정의되어 있어야한다. (익명함수 불가)
  • return 문이 없는 함수와, return 지시자 하나만 있는 undefined를 반환한다.

Function Expression

  • 함수 표현식은 정의한 function을 별도의 변수에 할당한다.
let sayHi = function () {
  alert("Hello");
};
  • 위에선 sayHi라는 변수에 할당하는 구문이므로 세미콜론 ; 붙여야함 (convention)
  • 함수는 구문이기도 하면서 값이다.
  • 콜백함수
    • 함수를 값 처럼 전달하는 예시 : confirm의 결과에 따라 인자로 전달된 yes or no 함수가 실행된다.
    • 익명함수 사용 : 함수에 이름을 붙이지 않고 아래와 같이 사용할 수도 있다. 대신 이름이 없으므로 해당 스코프 밖에선 사용할 수 없다.
function ask(question, yes, no) {
  if (confirm(question)) yes();
  else no();
}

ask(
  "동의하십니까?",
  function () {
    alert("동의하셨습니다");
  },
  function () {
    alert("취소하셨습니다");
  }
);

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

차이점 1 : 자바스크립트 엔진이 함수를 언제 생성하는지

  • 함수 선언문 : 스크립트를 실행하기 전 준비단계에서 생성되므로, 어디에서나 함수를 사용할 수 있음.
  • 함수 표현식 : 실제 실행 흐름이 함수에 도달했을 때 함수를 생성. 따라서 흐름이 도착했을 때 이후부터 함수를 사용할 수 있음.

호이스팅 관점에서 보면, 변수는 선언부분만 끌어올리고 함수 선언문은 함수 전체를 끌어올린다. 따라서 함수 선언문은 해당 함수를 정의한 행 이전에도 함수를 호출할 수 있다. 하지만 함수 표현식의 경우, 함수가 할당된 변수만 먼저 호이스팅 되기 때문에 실행 흐름이 함수에 도달하지 않은 상태에서 함수를 사용하면 에러가 발생한다. 함수 선언문은 동일한 이름의 함수를 한번 더 정의하면 이전의 함수가 덮어씌어진다. 이럴 경우 이전에 정의한 함수를 호출한 코드의 동작까지 모두 바뀌는데 오류도 발생하지 않아서 디버깅이 힘들어진다. 이런 상황을 방지하기 위해 함수 표현식을 사용하는게 비교적 안전하다. 물론 함수들을 감싸서 지역변수로 만드는 방법이 더 좋긴함.

차이점 2 : 스코프

  • 함수 선언문 : 함수가 선언된 블록 안에서만 어디에서나 유효하다.
  • 함수 표현식 : 전역으로 선언한 변수에 함수를 할당해주면 블록 밖에서도 사용할 수 있다.

 


참고