🍁 Function
자바스크립트의 함수는 1급 객체(First Citizen)라는 말이 있다.
1급 객체는 자바스크립트에서만 볼 수 있는 현상은 아니고, 다른 언어(Switf - 아이폰 개발 언어, Python 등)에서도 볼 수 있는 현상이다.
이는 쉽게 말하자면 함수를 객체처럼 취급하여 함수를 값(데이터)으로 사용할 수 있게 하는 것이다.
자바스크립트 Function에 대해서는 위 글을 참고한다.
함수가 데이터라면 무엇을 할 수 있을까?
- 함수를 변수나 데이터 구조에 저장할 수 있다.
- 함수를 매개변수를 전달할 수 있다.
- 함수를 반환값으로 사용할 수 있다.
함수는 행동이지 데이터가 아니다.
그런데 만약 함수가 데이터가 되면 위와 같은 행동을 할 수 있게 된다.
함수의 선언
1. 함수 선언문
2. 함수 표현식(리터럴)
//함수 선언문
function m1() {
alert('m1');
}
m1();
//함수 표현식
function () {
alert('익명 함수');
}
함수 표현식은 이름을 만들지 않고, 매개변수 리스트가 온다.
즉, 이름이 있는 함수를 함수 선언문이라고 하고, 이름이 없는 익명 함수를 함수 표현식이라고 한다.
변수에 익명 함수 저장
//함수 표현식
let f2 = function () {
alert('익명 함수');
}
f2();
function m3() {
alert('m3');
}
let f3;
f3 = m3;
//m3();
f3();
함수 표현식으로 선언한 함수를 변수에 저장할 수 있다.
그러면 변수를 함수처럼 사용할 수 있게 된다.
변수를 함수처럼 호출하더라도 같은 결과가 출력되는 것을 볼 수 있다.
익명 함수에 이름이 없는 이유
let f4;
f4 = function m4() { //f4 = function ()
alert('m4');
};
f4();
//m4(); //호출 X
이 경우에는 에러가 발생한다. 함수가 바깥쪽에서 별도로 정의되는 게 아니라 함수를 변수에 넣는 것과 동시에 선언되면 외부에서 사용할 수 없게 되기 때문이다.
이처럼 선언과 동시에 변수에 넣는 함수에 한해서는 이름 있는 함수를 바깥에서 호출할 수 없으므로 주의가 필요하다. 그래서 익명 함수에 이름이 없는 것이기도 하다.
익명 함수를 활용한 이벤트 전용 함수의 잘못된 사용 방지
<input type="button" value="버튼" id="btn1">
document.getElementById('btn1').onclick = p1;
function p1() {
alert('btn1');
}
p1(); //잘못된 사용
p1은 클릭을 btn1의 클릭 이벤트 전용 함수인데, 바깥쪽에서 호출하는 것은 잘못된 사용이다.
잘못된 사용을 했는데도 에러가 나지 않다. 이러한 사용을 방지하도록 해보자.
function p1() {
alert('btn1 > ' + event.buttons);
}
이벤트에 이름 있는 실명 함수를 쓰게 되면 에러가 발생한다.
이럴 때 익명 함수를 사용할 수 있다!
document.getElementById('btn2').onclick = function () {
alert('btn2');
};
이벤트 안에 직접적으로 익명 함수를 정의하면 이름이 없으므로 바깥쪽에서 호출 자체가 불가능해진다.
이렇게 작업을 하면 함수를 다른 용도로 사용하지 않게 되므로 가독성이 향상된다.
이는 BOM 방식이므로 DOM 방식으로 만들어보도록 하자.
//실명 함수를 사용하는 방법
document.getElementById('btn3').addEventListener('click', p3);
function p3() {
alert();
}
//익명 함수를 사용하는 방법
document.getElementById('btn3').addEventListener('click', function(){
alert();
});
p3가 들어갈 장소에 익명 함수를 바로 넣어서 사용한다.
함수의 다양한 사용
function m5() {
alert();
}
function m6() {
m6(m5);
}
function m6(aaa) {
aaa();
}
m6(m5);
m6(function() {
alert('익명 함수');
})
function m7() {
alert('m7');
}
function m8() {
return m7;
}
let temp = m8();
setTimeout(function() { //1초 뒤에 alert 실행
alert();
}, 1000);
함수를 인자값으로 함수를 호출할 수 있으며, 리턴값을 함수처럼 호출할 수 있다.
결론적으로 함수를 값처럼 호출할 수 있다.