본문 바로가기
javascript

[자바스크립트] 함수 호이스팅

by jinbro 2017. 4. 20.

[목표]

- 자바스크립트 내부 동작 잘 이해하기 : 코드를 복붙하더라도 알고 써야지!


[호이스팅이란]
- 선언문이 최상위에서 처리되는 것을 호이스팅이라 함
- 글로벌 영역(전역)으로 선언되어있는 변수, 함수 선언문들을 먼저 수집하여 전역객체(window)의 프로퍼티로 등록함
- 할당문은 자바스크립트 코드 실행(런타임 과정) 시 할당됨


[발생하는 이유]
- 자바스크립트의 선언문은 자바스크립트 인터프리터가 해석을 할 때 가장 먼저 처리함(최상위)


[호이스팅 예시 - 함수]
1
2
3
4
5
6
7
function foo(){
     console.log("함수선언식")
}
 
var foo = function(){
     console.log("함수표현식")
}
cs
- 같은 함수인 것 같지만, 호이스팅에서 차이가 남, 아랫글이 차이에 대한 부분임

1-1) 첫번째 함수선언식은 말그대로 함수를 선언한 것이기 때문에 선언부 전체(함수 전체 - 실행문까지)를 가져감
1-2)  함수선언식은 실행문이 아닌 선언문을 먼저 가져와 처리하는 것 : 함수 내부 함수가 있으면 함수 처리부터, 실행문은 할당된 후 실행될 때만
1
2
3
4
5
6
7
8
9
10
11
12
function foo(){
     function bar(){
          console.log("1")
     }
 
     return bar()
 
     function bar(){
          console.log("2")
     }
}
foo()
cs

1-3)  선언문부터 처리 : foo -> foo statement {} 내부 처리 -> bar 처리(선언문) -> bar 처리(선언문)
1-4) 결국 순서는 "2"가 콘솔창에 찍히는 함수선언문이 return bar() 보다 위로 가게됨 
1-5) 결과적으로 bar()는 "2"가 찍히는 bar() 함수를 뜻하게 됨
1-6) 함수선언문으로 선언되면 최상위로 처리됨
1-7) 함수선언문으로 함수 처리를 할 때에는 호이스팅을 염두해둬야함
1-8) 전역 Variable Object(전역객체) 생성과 관련 있음 : 실행컨텍스트 포스팅 참고
- VO가 생성될 때 함수명을 프로퍼티로 놓고, 함수객체를 프로퍼티의 값으로 놓음
- 함수객체 생성 : Variable Object 생성 > arguments 객체 생성, 지역변수, 함수, 스코프, this 바인딩


2-1) 두번째 함수표현식은 변수에 함수를 할당하는 것, 전역변수라 전역객체 프로퍼티로 등록되지만, 함수는 할당문으로 런타임 시 할당됨
- 인터프리터는 기계어로 번역한 후 바로 실행 : 함수가 동작(호출 될 때)할 때 할당
- 함수의 Variable Object(함수객체) 생성과 관련 있음 : 함수를 담을 변수의 명은 전역객체 프로퍼티로 설정되고, 값으로는 아직 undefined가 할당됨
2-2) 함수는 선언 방식에 따라 호이스팅으로 인해 다르게 동작함


[호이스팅 조심해야할 점]
1) 함수선언식의 경우 선언문보다 호출문이 앞에 있어도, 인터프리트 시 최상위에서 처리되기때문에 오류 없이 실행 잘 됨

2) 함수표현식의 경우 함수를 할당할 변수만 최상위에서 처리되고 함수 할당이 되지않으므로 순서가 바뀌어서는 안됨



[함수 팁]
1) 함수표현식은 함수리터럴로 변수에 할당하거나, 즉시 실행가능한 코드로 사용할 수 있음
1
2
3
4
5
6
7
8
9
10
/* 변수할당 */
var foo = function(){
     console.log("function expression")
}
 
/* 자기호출함수 : () 로 함수를 감싸 바로 실행할 수 있도록 */
(function foo(){
     console.log("function expression")
})()
 
cs

- 함수선언은 정의를 하는 것이지, 바로 실행가능한 코드가 아님 : 정의가 되더라도 실행된 것이 아님

- 함수표현은 () (괄호)를 씌움으로서 바로 실행가능한 코드로 사용할 수 있음



댓글