티스토리 뷰
먼저, 선언적 함수와 익명 함수의 차이점을 알아 보기 전에 함수를 정의하는 방법에 대해서 알아보자!
자바스크립트의 함수는 function 키워드로 정의한다.
함수를 정의하는 여러가지 방법이 있다.
대표적으로 함수 선언식(Function Declarations)과 함수 표현식(Function Expressions)가 있다.
$ 함수 선언식(Function Declarations)
function functionName(parameters) {
// code to be executed(실행될 코드)
}
$ 함수 표현식(Function Expressions)
: 표현식을 사용하여 함수를 정의한다. 함수명을 생략하는 것이 일반적이라고한다.
// 익명 함수 표현식(anonymous function expression)
var x = function (a, b) {return a * b };
// 기명 함수 표현식(named function expression)
var y = function multiply(a, b) {return a * b};
특징 : 함수 표현식은 변수에 할당한다. 해당 변수는 함수로서 사용할 수 있다. 함수 호출 시, 변수 이름을 사용해서 함수를 호출한다.
기명 함수의 함수 명으로 호출 시, 에러가 발생한다. 함수 표현식에서 사용한 함수명은 외부 코드에서 접근이 불가능하기 때문이라고 한다.
var z = x(4,3);
console.log(z); // 12
var y = multiply(4,3); // Uncaught ReferenceError: multiply is not defined
y(4,3); // 12
위의 함수 정의들은 function 키워드가 필요했다.
하지만 자바스크립트에 3 ) 내장된 함수 생성자(Function Constructor)인 Function()으로 함수를 정의할 수 있다.
var myFunction = new Function("a","b","return a * b");
var x = myFunction(4,3);
근데 함수 생성자를 사용해서 함수를 정의하지는 않는다.
함수 생성자를 사용해 정의한 함수를 함수 표현식으로 표현할 수 있다.
var myFunction = function (a,b) {return a * b};
var x = myFunction(4,3);
$ 그래서 선언적 함수랑 익명 함수의 차이점이 뭔가?
함수 호출 순서의 차이가 있다. 만약 함수를 먼저 호출하고 선언할 경우, 선언적 함수의 경우 호이스팅으로 인하여 런타임(컴퓨터 프로그래밍이 실행되고 있는 동안의 시간)에서 에러가 발생하지 않는다. 하지만 익명 함수는 글로벌 영역에 먼저 등록되지 않기 때문에(?)먼저 호출시 에러가 발생한다.
즉, 선언적 함수는 호이스팅에 영향을 받지만, 익명 함수는 호이스팅에 영향을 받는다.
아래의 예시 코드를 보자! (익명 함수 호출 할 때, 발생할 수 있는 에러!)
// 함수 test는 함수 선언문(선언적 함수)
function test() {
console.log(printName());
// 함수 printName는 함수 표현식
var printName = function() {
return 'anonymouse';
}
}
test();
//TypeError: PrintName is not a function
$ 왜? TypeError: PrintName is not a function가 발생했을까?
아래의 코드를 확인해보면, 자바스크립트 함수가 실행되기 전에, 함수 안에 변수들을 자바스크립트 파서가 var printName 변수를 끌어올려 선언한다(호이스팅). 즉, 변수 printName에 값이 할당되기 전에 printName() 실행됐기 때문에 undefined가 할당된다. 그리고 undefined는 함수가 아니기 때문에 타입에러가 발생한다.
// 함수 test는 함수 선언문(선언적 함수)
function test() {
// printName는 함수 표현식
console.log(printName());
var printName; // undefined; 선언은 되었지만 할당은 되지 않았다는 뜻이다. 즉, printName은 함수로 인식되지않았다는 뜻이다
printName = function() {
return 'anonymouse';
}
}
test();
//TypeError: PrintName is not a function