본문 바로가기

책/인사이드 자바스크립트

8day - 함수와 프로토타입 체이닝 (2)

1)함수 호이스팅

함수 생성 방식에 대해서 앞에서 알아봤는데 이들 사이에는 동박 방식이 약간 차이가 있다.

그중에 하나가 바로 함수 호이스팅(Function Hoisting)이다.


더글러스 크라포드는 자바스크립트 핵심 가이드 에서 함수 표현식만을 사용할 것을 권하고 있다.

그 이유중 하나는 함수 호이스팅 때문이다. 

1
2
3
4
5
6
7
8
add(2,3//5 (1)
 
// 함수 선언문 형태로 add () 함수 정의
function add(x, y) {
    return x + y;
}// (2)
 
add(34);  // 7 (3)
cs

1) 함수가 자신이 위치한 코드에 상관없이 함수 선언문 형태로 정의한 함수의 유효 범위는 코드의 맨 처음부터 시작한다.  이것을 함수 호이스팅이라고 부른다.


함수 호이스팅은 함수를 사용하기 전에 반드시 선언해야 한다는 규칙을 무시하므로 코드의 구조를 엉성하게 만들 수도 있다고 지적 했고 함수 표현식 사용을 권장하고 있다.

1
2
3
4
5
6
7
8
add(23); //unacught type error  (1)
 
// 함수 표현식 형태로 add() 함수 정의
var add = function (x, y) {
    return x + y ;
};// (2)
 
add(34)   // 7   (3)
cs

1)아까 전과 달리 (1)에서는 호이스팅이 일어나지 않는다. (3)과 같이 함수가 생성된 이후에 호출이 가능하다.

이러한 함수 호이스팅이 발생하는 원인은 자바스크립트의 변수생성(Instantiation) 과 초기화(Initialization)의 작업이 분리 돼서 진행 되기 때문이다.


2)함수 객체 : 함수도 객체다

2-1) 자바스크립트에서는 함수도 객체다

함수도 객체다. 즉 함수의 기본 기능인 코드 실행뿐만 아니라 함수 자체가 일반 객체처럼 프로퍼티들을 가질 수 있다는 것이다.

1
2
3
4
5
6
7
8
9
10
11
//함수 선언 방식으로 add()함수 정의
function add(x, y) {
    return x + y;
}  // (1)
 
// add () 함수 객체에 result, status프로퍼티 추가
add.result = add(3,2);  // (2)
add.status = 'OK';      // (3)
 
console.log(add.result);   // 5
console.log(add.status);   // OK
cs

1)add () 함수를 생성할 때 함수 코드는 함수 객체의 [[Code]] 내부 프로퍼티에 자동으로 저장된다.

2) (2),(3) add () 함수에 마치 일반 객체처럼 프로퍼티를 동적으로 생성한다.

3) add () 함수 객체의 status 프로퍼티도 일반객체에서 접근 방식ㅊ처럼 add.status를 이용해 접근 가능하다.

이처럼 함수는 특정 기능의 코드를 수행하는 역활뿐만 아니라 일반 객체처럼 자신의 프로퍼티를 가질 수 있는 특별한 객체라고 볼 수 있다.

2-2)자바스크립트에서 함수는 값으로 취급된다

함수도 일반 객체처럼 취급될 수 있다.

  • 리터럴에 의한 생성
  • 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
  • 함수의 인자로 전달 가능
  • 함수의 리턴값으로 리턴 가능
  • 동적으로 프로퍼티를 생성 및 할당 가능

이와 같은 특징이 있으므로 자바스크립트의 함수를 일급(First Class)객체 라고 부른다.

일급객체의 특성으로 함수형 프로그래밍이 가능하다.

일급객체는 함수가 일반 객체처럼 값(Value)으로 취급된다는 것을 이해해야 한다.

함수를 변수나 객체, 배열 등에 값으로도 저장할 수 있으며, 다른 함수의 인자로 전당한다거나 함수의 리턴값으로도 사용이 가능하다.


2-3)변수나 프로퍼티의 값으로 할당

함수는 숫자나 문자열처럼 변수나 프로퍼티의 값으로 할당될 수 있다.

1
2
3
4
5
6
7
8
9
//변수에 함수 할당
var foo = 100//(1)
var bar = function () { return 100; }
console.log(bar()); // 출력값 100
 
//프로퍼티에 함수 할당
var obj = {};
obj.baz = function () { return 200; }
console.log(obj.baz()); // 출력값 200
cs

1)foo와 bar 할당문의 차이는 bar는 함수의 참조값을 저장하고 있으므로, bar()라고 했을때 실제 함수의 호출이 가능하다는 것이다.

2)함수는 (1)과 같이 변수 이외에 예제의 baz처럼 객체의 프로퍼티나 배열의 원소등에도 할당이 가능하다.