우와한 개발자

[JavaScript] 렉시컬(Lexical), 호이스팅(Hoisting), 클로저 (Closure)

by 우와한개발자

[렉시컬(Lexical) ]

1) 렉시컬(Lexical)
  • 코드가 어디에 작성되어 있는지를 기준으로 동작이 결정되는 것

2) 렉시컬 스코프 (Lexical Scope)

  • 변수의 접근 범위가 함수가 선언된 위치에 의해 결정되는 것
var data = 10;

function print() {
  console.log(data);
}

function test() {
  var data = 20;
  print();
}

test(); //10
Global
 ├ data = 10
 ├ print()
 └ test()

→ print()는 Global에서 선언된 함수이므로 test() 안에서 호출되더라도 test의 data가 아니라 global의 data를 사용

 

var data = 10;

function outer() {
  var data = 20;

  function inner() {
    console.log(data);
  }

  inner();
}

outer(); //20
Global
 └ outer
     └ inner

 inner 함수는 outer 안에서 선언됐기 때문에 outer의 data를 사용

 

[ 호이스팅(Hoisting) ]

  • 변수나 함수 선언이 코드의 최상단으로 끌어올려진 것처럼 동작하는 JavaScript의 동작 방식
  • 실제로 코드가 이동하는 것은 아니고 자바스크립트 엔진이 실행 전에 선언을 먼저 처리

 

1. 변수 호이스팅

console.log(a); //undefined
var a = 10;
var a; 선언(var a) //→ 먼저 처리
console.log(a);
a = 10; //값 할당(a = 10) → 나중 실행

 

2. let / const 호이스팅

console.log(a); // ReferenceError
let a = 10;

→ TDZ (Temporal Dead Zone) 때문

 

1) TDZ (Temporal Dead Zone)란

  • 변수가 선언되기 전까지 접근할 수 없는 구간
  • 변수는 이미 스코프에 존재하지만 초기화되기 전까지 접근할 수 없음
// 실행 컨텍스트 생성 단계
let a; // 스코프에 등록되지만 초기화 안됨

// TDZ 구간
console.log(a); // 접근 시 에러

// 초기화
a = 10;

 

3. 함수 호이스팅

1) 함수 선언문 

hello(); // hello

function hello() {
  console.log("hello");
}

 

2) 함수 표현식 

hello(); // TypeError

var hello = function () {
  console.log("hello");
};

 

[ 클로저 (Closure) ]

  • 내부 함수를 반환값으로 사용하는 패턴.
  • 각 호출마다 독립된 변수 공간을 가진 인스턴스 반환
  •  함수가 선언될 때의 외부 변수 환경을 기억하여 그 변수에 계속 접근할 수 있는 함수
function outer() {
  var x = 0;
  return function() { return ++x; }
}

const f = outer();
const g = outer();

f(); // 1
f(); // 2
g(); // 1 (f와 독립적)
  • 메모리구조
f
 └ closure
     x = 0 → 1 → 2

g
 └ closure
     x = 0 → 1

 

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기