자바스크립트의 함수는 양자역학의 중첩 상태이다. 관찰하는 순간 결정되는 것이다.
변수가 될 수도, 매개변수가 될 수도, 리턴값이 될 수도 있는 것이여...
0. 초능력자 자바스크립트 함수
자바스크립트에서 함수는 일급 객체(First Class Object)라고 불린다.
일급 객체는 다른 어떤 객체와도 같이 제한 조건이 없이 사용된다는 의미이다.
크게 3가지가 인터넷에 예시가 많은데,
간단한 함수 하나를 만들어서 설명해보자.
doubleNumber라는 함수를 선언한다.
기능은 정말 간단하다. 하나의 숫자를 받으면 2배를 해서 리턴해준다.
let doubleNumber = ( number ) => ( number * 2 );
// 화살표 함수 표현식
let doubleNumber2 = function(number) { return number * 2 }
// 함수 표현식 (function expression)
// 함수 선언문
function doubleNumber3( number ) {
return number * 2
}
위의 3가지는 모두 같은 기능을 구현하는 함수인데 표현하는 방식이 다르다.
같은 기능을 하는 함수라도 선언하는 방식에 따라서 문제가 발생하는 경우가 있는데
그건 조금 후에 알아보자.
1. 일급 객체로서 사용되는 조건의 예시
첫번째, 변수에 할당할 수 있는가? ( 가능 )
let doubleNumber = ( number ) => ( number * 2 ); // 화살표 함수 표현식
변수에다가 함수를 넣었다. 말도 안돼. 코끼리를 냉장고에 넣다니.
자바스크립트에서는 가능하다.
심지어 함수를 객체에다가 넣을 수도 있고, 배열에도 밀어 넣을 수 있다.
// 객체 안에다가 함수를 넣었음.
let exampleObject = { myFunction: doubleNumber }
// 배열에다가 함수를 넣었음.
let myArray = [];
myArray.push( doubleNumber );
아래 사진은 크롬 브라우저에서 직접 실행한 결과이다.
두번째, 매개변수로 전달될 수 있다.
function doubleNumber(number) {
return number * 2
}
function doubleWhateverYouWant(doubleFunction, doubleIt) {
// 함수를 매개변수로 전달했다.
console.log(doubleFunction(doubleIt) + 5);
}
doubleWhateverYouWant(doubleNumber, 2); // 9
// 2가 들어가서 2배가 된 이후에 5랑 더해져서 9가 됨
세번째, 리턴값으로 사용될 수 있다.
function doubleNumber(number) {
return () => {
// 리턴값 자체가 숫자의 2배를 출력하는 함수
console.log('2배는?' + number * 2);
}
}
doubleNumber(4)
이 경우에는 콘솔이 찍히지는 않는다. 대신 콘솔을 찍는 "함수 자체"가 리턴된다.
2. 그건 그렇다치고, 함수 호이스팅이란게 뭔데?
저렇게 되면 문제가 생긴다.
뭐냐면,
let doubleNumber로 변수를 선언해두고 거기에 함수를 넣었을 때
doubleNumber는 함수인가 변수인가?
"아니 이게 뭔소리여, 그냥 변수에 넣은 함수지~" 라고 할 수 있지만
정확히 말하면 변수에다가 함수를 넣는 방식을 "함수 표현식" 이라고 부르며,
function 함수명(value) { return value; }
이런 식으로 적는 것을 "함수 선언문"이라고 부르는데
두 가지는 약간 다르게 작동한다.
예시를 보자.
let a = 10
let b = 20
add1(a, b);
add2(a, b);
function add1(num1, num2) {
console.log(num1+num2) // 실행되는지를 확인 위해 더한 값을 출력한다.
}
let add2 = (num1, num2) => num1+num2; // 그냥 더해만 보자.
똑같은 기능을 구현한 함수를 만들고 함수가 선언되기 이전에 둘 다 불러봤다.
어떻게 될까?
정답은,,,
아래 함수는 오류를 내며 수행되지 않는다는 것이다.
그 이유는
일반 함수로 선언을 하는 경우에는 브라우저가 실행할 때 자바스크립트 엔진이 전체를 해석하면서
어디서든 실행 가능하도록 미리 상단으로 끌어올려놓는다.
이것을 "호이스팅" (Hoisting)이라고 부른다.
그래서 전역에서 함수를 사용하고 싶을 때는 변수에 넣는 형식이 아니라
function으로 시작하는 함수 선언문을 사용해야한다.
끝!