함수
자바스크립트의 함수는 '객체'이다. 함수는 객체이기 때문에 변수에 할당할 수 있고, 프로퍼티를 가질 수 있으며, 함수를 인자로 전달할 수도 있다. 또한 함수는 함수를 반환할 수도 있다. 함수는 좀더 특별한 객체이다. 함수는 호출될 수 있기 때문이다. 함수는 일반 객체와는 달리 호출될 수 있기 때문에 '호출 가능한 객체'라고도 부른다.
함수 객체 생성
함수 객체를 생성하는 몇가지 방법이 있다. '함수 선언문', '함수 표현식', '화살표 함수', 'Function() 생성자 함수' 등이 있다.
함수 선언문
function
키워드를 사용해 함수 객체를 정의하는 '함수 선언' 방식이다. 함수 선언문은 함수 이름을 생략할 수 없다.
여기서 add
는 함수 이름이다. 함수 선언 방식으로 정의된 이 함수 이름은 '변수'라는 것을 기억할 필요가 있다. const
로 지정된 변수가 아니기 때문에 재할당이 가능하다. 예를 들어서 다음은 add
함수를 '함수 표현식'을 사용해 재할당하는 코드이다.
또는 원래와 같은 형태의 함수 선언문을 사용해 재할당할 수도 있다.
의도하지 않은 재할당을 방지하기 위해 다음 섹션에서 설명하는 '함수 표현식'과 'const
변수'를 사용하는 것이 더 나은 선택일 수도 있다.
함수 선언문을 통해서 정의된 함수는 자신을 포함하는 스크립트, 함수 또는 불록의 선두로 '호이스팅(hoisting)' 된다. 여기서 '함수 호이스팅'이란 스코프 내부 어디서든 변수 선언문이 선언된 것처럼 동작하는 것을 말한다. 함수 선언문은 함수 이름을 생략할 수 없다고 했는데, 이는 호이스팅이 함수 이름을 변수로 인식하기 때문이다. 정확한 비유는 아니겠지만 'C/C++'에서 같은 소스 파일 내의 하단에 존재하는 함수의 '함수 원형'을 그 소스 파일 최상단에 '전방 선언'해주어 해당 소스 파일내에서 어디서든 해당 함수를 호출할 수 있도록 하는 것과 비슷한 상황이라고 생각할 수도 있다.
함수 표현식
function
키워드를 사용한다는 점은 '함수 선언(declaration)'과 동일하다. '함수 표현식'은 말그대로 '표현식(expression)'이라는 점이 다르다. '선언'은 '문(statement)'이다. 선언을 통해서 정의된 함수 객체는 먼저 '함수 선언문' 섹션에서 설명한 것과 같이 '호이스팅'된다. '표현식'은 '값(value)'이다. 표현식은 코드가 실행되는 시점에 평가되어 '값'을 생성한다. '함수 표현식'은 함수 리터럴을 사용해 함수를 정의하고, 함수 리터럴은 함수 객체를 생성한다. 표현식을 통해서 정의된 함수 객체는 호이스팅되지 않는다. 함수 선언문을 사용해 함수를 정의하는 것과 다르게 함수 이름을 생략할 수 있다. 함수 이름을 생략한 함수 표현식을 '익명 함수 표현식'이라고도 한다.
함수 표현식으로 생성한 객체는 보통 const
로 선언한 변수에 할당한다. 이렇게 하면 재할당을 방지할 수 있다.
함수 표현식을 통해서 생성한 함수 객체에도 '함수 이름'을 지정할 수 있다. 이렇게 하면 '재귀 함수'를 구현할 수도 있다.
이 예제의 fact
함수는 '재귀 함수'이다. fact
함수는 자신을 참조하는 fact
식별자를 통해 자신을 호출한다. 이렇게 함수 이름을 지정한 함수 표현식을 '기명 함수 표현식(Named Function Expression)'이라고 한다. 기명 함수 표현식은 함수 이름을 통해 함수 내부에서 자신을 재귀 호출할 수 있다. 또한 함수 이름을 통해 함수 내부에서 자신을 참조할 수 있다. 하지만 함수 이름은 함수 몸체 내부에서만 참조할 수 있다. 함수 몸체 외부에서는 참조할 수 없다.
'함수 표현식'은 곧바로 함수 객체를 생성하기 때문에 '즉시 실행 함수(IIFE, Immediately Invoked Function Expression)'를 생성할 수 있다. '즉시 실행 함수'는 함수 정의와 동시에 호출되는 함수를 말한다. '즉시 실행 함수'는 함수를 정의함과 동시에 호출하기 때문에 단 한번만 호출된다. 이러한 특성을 이용해 '최초 한번의 실행만을 필요로 하는 초기화 코드'를 즉시 실행 함수로 만들어 사용할 수 있다.
화살표 함수
'화살표 함수(Arrow Function)'는 ES6에서 도입된 새로운 함수 정의 방식이다. 화살표 함수는 함수 표현식을 간략하게 표현할 수 있도록 해준다. 상황에 따라서 다양한 표현을 사용할 수 있다.
자바스크립트에서 '문장'의 종결에 '세미콜론'을 사용하지 않아도 되기 때문에 화살표 함수 표현을 사용해 함수 객체를 생성시 주의가 필요하다. 화살표 함수 표현식의 =>
키워드를 '함수 파라미터'와 '다른 줄'로 내려서 작성하면 문제될 수 있다. 예를 들어서 다음과 같이 작성된 화살표 함수 표현은 의도하지 않은 변수 선언을 한 것으로 해석된다.
위의 코드는 자바스크립트 인터프리터가 다음과 같이 해석을 시도하게된다.
이 예제 코드의 경우 결과적으로 '문법 오류'가 발생한다. 화살표 함수 표현식을 사용할 때는 적어도 =>
키워드를 '함수 파라미터'와 '같은 줄'에 반드시 작성해야 한다. 함수 몸체는 다른 줄에 작성해도 상관없다.
Function() 생성자 함수
함수 리턴값
함수는 항상 리턴값을 반환한다. 명시적인 리턴값이 없는 경우에는 undefined
를 반환한다고 해석된다.
this 키워드
'함수'내에서 사용되는 this
키워드의 해석이 상황에 따라서 다르다. 즉 '전역 함수, 메서드, 화살표 함수' 등의 상황에 따라서 this
키워드의 해석이 다르다.