JavaScript

12. Js의 함수(함수 호이스팅)

문정훈 2022. 5. 5. 17:04

1. 함수란

1) 함수란?

함수란 일련의 과정을 문(최소 실행 단위)으로 구현하여 코드 블록으로 감싸 하나의 실행 단위로 정의한 것이다. 

js에서 함수를 생성하는 방법은 함수 정의를 통해 생성한다.

 

※ 리터럴의 뜻

값을 생성하기 위한 표기법으로 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용하여 값을 생성하는 표기법을 말한다. 

 

2) 함수 리터럴

js에서 함수는 객체 타입의 값이다. 함수 리터럴은 function 키워드, 함수 이름, 매개변수, 함수 몸체로 구성된다. 

var f = function add(x, y) {
	return x + y;
}
// 변수 f에 함수 리터럴을 할당하여 함수를 만들 수 있다.

함수 리터럴은 평가 과정을 통해 값이 되며 이는 객체로 간주된다. 즉 함수 리터럴은 평가되면 객체가 된다. 


 

 

2. 함수의 정의

여러가지 함수 정의 방식

js에서 함수를 생성하는 방법으로 함수 정의를 통해 생성한다. 다양한 함수 정의 방법을 정리하면 총 4가지 방법이 있다. 

  1. 함수 선언문
  2. 함수 표현식
  3. Function 생성자 함수
  4. 화살표 함수

이 중 1번과 2번에 대해 정리하겠다. 

 

1) 함수 선언문

● 함수 선언문

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

console.log(add(1,2));

함수 선언문은 표현식이 아니라 문이다. 문이란 js가 실행하는 최소 실행단위, 표현식은 값으로 평가 될 수 있는 문을 말하는데 함수 선언문은 그 선언문 자체만으로 값으로 평가 되지 않는다. 따라서 표현식이 아닌 문이다. 

반면 함수 표현식은 표현식인 문이다.

 

● 호이스팅 : 함수 선언문 함수 호이스팅이 발생한다. 

console.log(add(1,2)); // 3 

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

0위 예시 코드를 보자. 위 코드가 평가 되면 (런타임 이전에 실행) console.log문은 평가 과정에서 실행되지 않고 평가 이후 실행 과정에서 동작한다. 

평가 과정에서 위 전역 코드는 우선 js엔진은 메모리 공간상에 add라는 식별자를 암묵적으로 만든다. 그리고 함수 리터럴로 표현된 즉 함수 선언문으로 정의한 함수의 객체아 heap 영역에 실제로 생성되고 그 heap 영역의 메모리 주소가 add 라는 암묵적 식별자에 할당된다. 

따라서 add라는 키워드를 통해 함수를 호출할 수 있는 것이다. 

 

함수 선언문은 선언문이 작성된 코드 이전에 함수를 호출할 수 있는데 그 이유는 함수 객체가 전역 코드의 평가 과정에서 먼저 생성되고 전역 코드의 실행 과정에서 add(1,2) 함수 호출문이 실행되기 때문에 올바르게 동작한다. 이 처럼 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 js의 고유한 특징을 함수 호이스팅이라고 한다. 

 

 

2) 함수 표현식

● 함수 표현식

var add = function (x, y) {
	return x + y;
}

console.log(add(1,2));

js에서 함수 리터럴은 값으로 처리되는 객체이다. 객체는 값이기 때문에 변수에 할당될 수 있고 배열의 요소가 될 수도 있다. 이 처럼 값의 성질을 갖는 객체를 일급 객체라고 한다. 따라서 함수는 일급 객체이다. 

 

함수 리터럴로 생성한 함수 객체를 변수에 할당할 수 있다. 이러한 방식으로 선언된 함수 정의 방식을 함수 표현식이라고 한다. 

 

 

● 호이스팅 : 함수 표현식은 함수 호이스팅이 아니라 변수 호이스팅이 일어난다. 

console.log(add(1,2)); //TypeError : add is not a function

var add = function (x, y) {
	return x + y;
}

위 코드가 실행되면 어떤 결과가 되는지 분석하면,

 

1. 전역 코드가 평가(런타임 이전의 실행 단계)되면 add라는 식별자가 메모리 공간에 할당되고 undefined 값을 가진다. 

 

2. 전역 코드의 평가 과정이 끝나고 실행 과정이 되면 아래 과정을 거친다.

  2-1. add함수가 호출된다 -> add 라는 식별자는 undefined를 할당하고 있으므로 에러 발생

  2-2. 함수 리터럴인 함수 표현식으로써 함수 객체가 생성되고 heap 영역에 저장된다. 그리고 add라는 변수에 함수가            저장된 주소 공간을 할당한다.

 

함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하지 않고 변수 호이스팅이 발생한다.

위 코드에서 변수 호이스팅이란 add라는 변수가 전역 코드의 평가 과정에서 먼저 undefined라는 값을 할당한다. 그리고 전역 코드의 실행 과정에서 add를 호출할 수 있다.(다만 undefined를 가진다는 점) 이 처럼 var 변수 코드의 선두로 끌어올려진 것 처럼 동작하는 것이 변수 호이스팅이다. 

 

시 코드는 함수 함수 호이스팅이 아니라 변수 호이스팅이 발생한 것이고 add라는 식별자에 접근은 가능하지만 unedfined 값을 가지고 있었고 이는 함수 형태의 값이 아니기 때문에 TypeError가 발생한 것이다.