함수 선언문과 함수 표현식

건둔덕 ·2022년 7월 7일
1

Javascript

목록 보기
18/28
post-thumbnail

함수 선언문

함수 선언문은 함수 리터럴과 형태과 동일하다. 단, 함수 리터럴은 함수 이름을 생략할 수 있지만 함수 선언문은 함수 이름 생략이 불가능하다.

함수 선언문의 함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자이다. 이는 함수 몸체 외부에서 함수 이름을 참조할 수 없으므로 함수 몸체 외부에서는 함수 이름으로 함수를 호출할 수 없다는 의미이다. 즉, 함수를 가리키는 식별자가 없다는 것과 마찬가지이다.

<script>
function foo() {
	console.log('foo')
}

foo(); // 'foo'
</script>

하지만 위의 예제에서 보이듯이 함수 선언문으로 정의된 함수는 foo라는 이름으로 호출할 수 있었다. foo는 함수 몸체 내부에서만 유효한 식별자인 함수 이름이므로 foo로 함수를 호출할 수 없어야 한다. foo라는 이름으로 함수를 호출하려면 foo는 함수 이름이 아니라 함수 객체를 가리키는 식별자여야 한다. 그런데 위 예제에서는 식별자 foo를 선언한 적도 없고 할당한 적도 없다.

자바스크립트 엔진은 함수 선언문을 해석해 함수 객체를 생성한다. 이때 함수 이름은 함수 몸체 내부에서만 유효한 식별자이므로 함수 이름과는 별도로 함수 객체를 가리키는 식별자가 필요하다. 함수 식별자가 없다면 생성된 함수 객체를 참조할 수 없으므로 호출할 수도 없다.

따라서 자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 거기에 함수 객체를 할당한다.

정리하자면 함수 선언문으로 생성한 함수를 호출한 것은 함수 이름 foo가 아니라 자바스크립트 엔진이 암묵적으로 생성한 식별자 foo이다. 함수 이름과 변수 이름이 일치하므로 함수 이름으로 호출되는 듯 하지만 사실은 식별자로 호출된 것이다.

함수 표현식

자바스크립트의 함수는 객체타입의 값이다. 값의 성질을 가지고 있는 객체를 일급 객체라고 말한다. 그렇기 때문에 자바스크립트의 함수는 일급객체라고 할 수 있다.

함수는 일급 객체이므로 함수 리터럴로 생성한 함수를 변수에 할당할 수 있다. 이러한 함수 정의 방식을 함수 표현식(function expression)이라고 한다.

<script>
var foo = function () {
	console.log('foo');
}

foo(); // 'foo'

var foo = () => {
	console.log('foo');
}

foo(); // 'foo'
</script>

함수 선언문으로 정의한 foo를 함수 표현식으로 정의한다면 위의 예시처럼 선언할 수 있다. 함수 표현식으로 정의를 하게 될 때는 함수의 이름을 생략할 수 있는데 이러한 함수를 익명 함수라고 한다. 함수 표현식을 사용할 때에는 함수의 이름을 생략하는 것이 일반적이다.

함수 선언문에서 살펴 보았듯이 함수를 호출할 때에는 함수 이름으로 호출하는 것이 아닌 함수를 가리키는 식별자로 호출을 해야한다. 함수 이름은 함수 몸체 내에서만 유효한 식별자 이므로 함수 이름으로 함수를 호출할 수 없다.

<script>
var foo = function abc() {
	console.log('foo');
}

// 식별자로 호출
foo(); // 'foo'

// 함수 이름으로 호출
abc(); // ReferenceError: abc is not defined
</script>
profile
건데브

0개의 댓글