JavaScript 를 공부할 때면 알아야할 호이스티와 클로저의 개념
여러번 숙지할때마다 조금 더 깊이 들어가게 된다. (다 - 다익선)
오늘도 의식의 흐름에 따라 정리를 해보았다.
JavaScript - 호이스팅(hoisting)과 클로저(closure)의 쉬운 이해
스코프
코드를 짤 때, 모든 시작은 변수를 선언하고 값을 넣는 것에서 출발한다.
근데 변수가 인기가 많아서 이곳 저곳 불려다니면 혼선이 생길 것이다.
그래서 스코프라는 개념으로 변수가 돌아다닐 수 있는 바운더리를 정해두었다.
글로벌 레벨 스코프는 코드 이곳저곳을 누빌 수 있다.
함수 레벨 스코프는 function() { 함수 안 } 에서만 누빌수 있다.
블록 레벨 스코프는 { 요런 블록 안 } 에서만 뛰놀 수 있다. (if 문이나 for 문 등이 있다.)
요런 스코프의 성질 때문에 여러 개념이 파생되게 되었다. 대표적인 개념이 호이스팅이랑 클로저이다.
호이스팅
호이스팅은 변수 선언문이 스코프의 최상단으로 올라가게 되는 개념을 말한다.
변수가 선언되거나 함수가 실행될 때, 해당 스코프의 lexical 환경을 기억하게 되는데, 그때 변수가 최우선적으로 먼저 선언된다.
function fooA() {
a = 2;
var a;
console.log(a) // 2
}
function fooB() {
console.log(a) // undefined
var a = 2;
}
fooA() 의 경우
호이스팅에 의해 var a; 가 최상단으로 끌려와 선언되었고,
그리고 순서대로 a = 2 라는 값이 저장된 후,
console.log(a) 를 호출하였으므로 값이 잘 나오지만
fooB() 의 경우
호이스팅에 의해 var a; 가 최상단으로 끌려와 선언되었다 할지라도,
순서대로 파싱할 때, console.log(a) 가 먼저 호출되었으므로 ( === a 값이 할당되기 전 )
undefined 가 나온다
자바스크립트 엔진이 컴파일 할 때, 아래처럼 2단계로 나누어 변수에 접근한다.
var a = 2; 라고 했을 때, var a; 만이 호이스팅 되어서 최상단에 선언되게 되는 것이다.
var a = 2;
- 변수 선언 var a; // 이부분만 호이스팅
- 변수 초기화 a = 2;
클로저
클로저는 자기보다 상위 스코프의 저장된 값들을 기억한다는 개념이다.
자바스크립의 만의 개념이 아니고 함수형 프로그래밍 언어들의 공통적인 특징이라고 할 수 있다.
자바스크립트의 실행컨텍스트와 lexical 환경에 대해 알고 있으면 이해에 큰 도움이 된다.
쉽게 말해서 우물안 개구리같은 inner 함수가 생전 첨보는 a 라는 값을 사용하려고 한다.
위에 유학경험이 있는 형인 outer 한테 물어본다 "outer 형, a 알아?"
형은 inner 한테 "아 그거 2 라는 값이야 " 라고 알려준다.
개구리인 inner 는 콘솔로그로 2를 출력한다.
본인은 모르지만 상위 스코프가 가진 값을 가지고 있다는 것이다. (스코프 체이닝)
function outer() {
let a = 2; // var, let, const 상관없이 상위 스코프의 값을 기억한다.
function inner() {
console.log(a); //2
}
inner();
}
outer();
여기서는 a 가 글로벌 스코프에 저장될 것이다.
inner() 에서 a 값을 찾았더니 없다. → 그렇다면 그다음 상위로 거기서도 없으면 → 그 다음 상위로 거슬러 올라가며 a 값을 찾는다.
let a = 2; // 3. 한단계 더 올라가보자. global 스코프 여기서 찾았다!
function outer() { // 2. 한단계 위로 올라가봤더니 outer 스코프 요기도 없네?
function inner() {
console.log(a); // 1. a값이 inner 스코프에서는 없네?
}
inner();
}
outer();
'JavaScript' 카테고리의 다른 글
JavaScript - This 에 대해서 (0) | 2023.07.30 |
---|---|
CSS - display 속성 inline / block / inline-block 이란 (0) | 2023.04.13 |
JavaScript - 동기와 비동기의 쉬운 이해 (0) | 2023.03.09 |
JavaScript - 유용한 정규식 예제들 (0) | 2023.03.02 |
JavaScript - 재귀함수 만들기(feat. 반복문 비교) (0) | 2023.03.01 |
댓글