내배캠/TIL(Today I Learned)

[TIL]내배캠 12일차 자바스크립트 함수 돌아가는 방식

도오라에몽 2023. 5. 31. 22:39

자바스크립트 함수에 대해서 학습을 했다.

함수에 대한 의문점

자바스크립트는 다른 프로그래밍 언어와는 다르게 함수 선언 방법이 4가지가 있다.
그 중에서 궁금했던 부분은 아래 세 가지 케이스다.

function add1(x, y) {
  return x + y;
}

const f1 = function (x, y) {
  return x + y;
};

const f2 = function add2(x, y) {
  return x + y;
};

console.log(add1(1, 2));    // Expected result: 3
console.log(f1(1, 2));        // Expected result: 3
console.log(f2(1, 2));        // Expected result: 3
console.log(add2(1, 2));    // ReferenceError: add2 is not defined

첫 번째와 두 번째는 그렇다 쳐도 세 번째는 왜 되는지 궁금했다.
그리고 찾아보니 생각지도 못한 것을 알게 되었다.

자바스크립트 엔진은 함수가 객체(일급객체)이다

이러한 자바스크립트의 특성 때문에 위의 두 번째 케이스같이 함수를 변수에 담을 수 있는 것이다.

이게 특이한 것은 자바스크립트는 함수 이름이 함수 내부에서만 참조할 수 있는 식별자라는 부분인데 그러면 왜 위 세 가지 케이스 중 첫 번째 케이스는 add1()로 사용할 수 있냐 하면, 자바스크립트 엔진이 암묵적으로 함수이름의 식별자를 만들어주기 때문이다.

그럼 위 예시의 세 번째 케이스가 왜 되는가?

그 이유는 자바스크립트 엔진이 {}(중괄호) 안에 있는 내용을 코드 문맥에 따라 객체 리터럴로 평가를 할지 블록문으로 해석을 할지를 정한다.
첫 번째 예시처럼 단독으로 {}(중괄호) 안에 들어있으면 블록문으로 해석하고 두 번째나 세 번째 예시처럼 피연산자로 사용되면 객체 리터럴로 해석을 한다.

조금 여기에서 첨언을 하자면 세 번째 예시에서 f2()가 아니라 add2()로 실행을 하면 에러가 발생한다.
위에서 첫 번째 케이스에 대한 설명을 할 때 언급했듯이 자바스크립트는 함수 이름을 함수 내부에서만 참조할 수 있다고 하였다. add2 함수가 현재 메모리에 있는 상황인데 그 add2 함수의 위치(주소)를 나타낼 수 있는 식별자가 없기 때문에 add2가 정의되어 있지 않다는 오류가 생기는 것이다. (add2()에 대해 이야기를 하는 것이고 현재 add2 함수는 변수(식별자) f2에 할당된 것이 맞다)

이렇게 함수 부분에 대한 설명을 남겨보았다..
(자바스크립트 너무 세부적으로 알게 많다...)