자바스크립트에서는 함수를 대하는 방식이 다른 언어와 조금 다르다. 특별한 동작을 하는 구조가 아닌 특별한 종류의 값으로 취급한다.
일반적으로는 함수 선언, 함수 선언문 방식으로 함수를 만든다.
function sayHi() {
alert( "Hello" );
}
외에도 함수 표현식(Function Expression)으로 함수를 만들 수 있다.
let sayHi = function() {
alert( "Hello" );
};
함수를 생성하고 변수에 함수를 할당하는 개념이다. 함수가 어떤 방식으로 만들어졌는지에 관계없이 함수는 값이기에, 변수에 할당할 수 있다.
function sayHi() {
alert( "Hello" );
}
alert( sayHi ); // 함수 코드가 보임
sayHi 함수가 실행되지 않고 코드만 보이는 이유는 호출 시 괄호를 붙이지 않아서이다. 특정 언어에서는 함수 이름만 언급해도 함수가 실행되지만 자바스크립트는 괄호가 있어야만 함수가 호출된다.
함수를 값으로 취급할 수 있기 때문이다. '기능'이 있는 특별한 값이라고 생각하면 될 것 같다.
그리고 값이기 때문에 값에 할 수 있는 일을 함수에도 할 수 있다.
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행(정상적으로 실행됨)!
sayHi(); // Hello // 본래 함수도 정상적으로 실행됨
/*-------------표현식으로 정의하여 복사하는 경우---------------*/
let sayHi = function() {
alert( "Hello" );
};
let func = sayHi;
// 두 방법의 동작 결과는 동일
위 두 방식의 미묘한 차이가 있다면 세미콜론의 유무이다. if(){}, for(){}, function f(){} 등의 코드 블럭(중괄호로 코드를 묶은 것) 끝엔 세미콜론이 없어도 된다. 하지만 함수 표현식은 let sayHi = ...;과 같은 구문 안에서 코드 블럭이 아닌 값처럼 취급되어 변수에 할당된다. 모든 구문의 끝엔 세미콜론을 붙이는 것이 좋다는 전제 하에, 함수 표현식 뒤의 세미콜론은 함수 표현식 때문에 붙여진 것이 아니라 구문의 끝이기에 붙여진 것이다.
콜백함수(Callback function)는 매개변수를 함수로 받아 나중에 호출하는 함수이다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
위 예시는
1) ask 함수 실행 시 confirm 창에 question 문구를 표시하고
2-1) 사용자가 확인 버튼을 누르면 yes 함수를,
2-2) 취소를 누르면 no 함수를 실행시킨다.
3) 하단의 코드에서 ask 함수 호출 시 동의 메세지, showOk, showCancel의 세 인자를 넣었다.
4) 따라서 사용자의 버튼 클릭에 따라 showOk 또는 showCancel 함수가 실행될 것이다.
5) 이 때 showOk, showCancel 함수가 콜백 함수 또는 콜백이라고 불린다.
익명 함수를 함수 내에서만 사용하게 할 수도 있다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
ask 함수 호출 시 인자 세 개중 두 개가 함수인데 함수명이 없다. 이렇게 이름 없이 선언한 함수를 익명함수(anonymous function)라고 한다. 익명 함수는 변수에 할당된 것이 아니기에 선언 시에 호출한 함수 외에서는 접근할 수 없다(느낌 상 제한이라기보다는 접근할 방법이 없겠다...).
표현식과 선언문의 차이
1) 문법
2) 엔진에서의 함수 생성 시점
3) 스코프(범위)
엄격모드에서
경우에 따라 선택해야 하겠지만 우선적으로 함수 선언문을 고려하는 것이 권장된다. 선언 이전에 호출이 가능하기도 하고, let 등으로 시작하는 코드보다는 function으로 시작하는 코드가 더 눈에 띄게 함수 같아 보이기 때문이다.