Javascript 실행 컨텍스트 와 클로져

김대은·2022년 7월 21일
0

제 자신의 공부를 위하여 제가 알기 쉽도록 기록한 것입니다.
공식문서와 다를 수 있습니다.

//예제 코드
var name = 'zero'; // (1)변수 선언 (6)변수 대입
function wow(word) { // (2)변수 선언 (3)변수 대입
  console.log(word + ' ' + name); // (11)
}
function say () { // (4)변수 선언 (5)변수 대입
  var name = 'nero'; // (8)
  console.log(name); // (9)
  wow('hello'); // (10)
}
say(); // (7)

실행 컨텍스트

처음 코드를 실행하는 순간 모든것을 포함하는 전역 컨텍스트가 생깁니다.
모든 것을 관리하는 환경이며, 페이지가 종료될 때까지 유지됩니다.
전역 컨텍스트 말고 함수 컨텍스트도 있는데,
함수를 호출 할 때마다 함수 컨텍스트가 하나씩 더 생깁니다.

컨텍스트의 4가지 원칙은 아래와 같습니다.

  • 먼저 전역 컨텍스트 하나 생성 후, 함수 호출시 마다 함수 컨텍스트 생성
  • 컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments, variable),스코프,체인,this,가 생성
  • 컨텍스트 생성 후 함수가 실행,사용되는 변수들은 변수객체안에서 값을찾고 스코프 체인 발생
  • 함수 실행이 마무리 되면, 해당 컨텍스트는 사라집니다.

전역 컨텍스트

전역 컨텍스트가 생성된 후 두번째 원칙에 따라 변수객체,스코프체인,this가 생성 됩니다.
전역 컨텍스트는 arguments 가 없고, variabled은 해당 스코프의 변수들 이다.

전역 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: ['name', 'wow', 'say'],
  },
  scopeChain: ['전역 변수객체'],
  this: window,
}

wow 랑 say 는 호이스팅 때문에 선언과 동시에 대입이 되며,
그 후 variable의 name 에 'zero' 가 대입됩니다.

variable: [{ name: 'zero' }, { wow: Function }, { say: Function}]

함수 컨텍스트

그 후 say(); 를 하는 순간 새로운 say 함수 컨텍스트가 생성됩니다.
arguments 는 없고, variable은 name 뿐입니다.
스코프 체인은 say 변수 객체와 상위의 전역 객체입니다.
this는 설정해 준 적이 없으니 window를 가져갑니다.

'say 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: ['name'], // 초기화 후 [{ name: 'nero' }]가 됨
  },
  scopeChain: ['say 변수객체', '전역 변수객체'],
  this: window,
}

이렇게 반복하여, 다음 wow 함수를 실행하여, wow 컨텍스트가 생깁니다.

wow 함수 종료 후 wow 컨텍스트가 사라지고, say 함수의 실행이 마무리 되면서
say 컨텍스트가 사라지며, 마지막에 전역 컨텍스트도 사라지게 됩니다.


호이스팅

호이스팅이란 ?
변수를 선언하고 초기화했을 때, 선언 부분이 최상단으로 끌어올려지는 것을 의미합니다.

console.log(name);//undefined
sayHi(); // 'Hi'
function sayHi(){
 console.log('Hi'); 
 }
 let name ='kim'

위 sayHi 처럼 함수 표현식이 아닌 함수 선언식일 경우는
함수 선언식 자체가 통째로 끌어 올려집니다.

sayWow(); // (3)
sayYeah(); // (5) 여기서 대입되기 전에 호출해서 에러
var sayYeah = function() { // (1) 선언 (6) 대입
  console.log('yeah');
}
function sayWow() { // (2) 선언과 동시에 초기화(호이스팅)
  console.log('wow'); // (4)
}

위 처럼 함수 표현식의 경우, 에러가 발생합니다.
위 코드를 실행 시 처음에 전역 컨텍스트가 생성 되는데
아시다시피 컨텍스트 생성 및 코드는 순차적으로 실행됩니다.
sasyYeah 는 대입되기전에 호출되어 에러가 발생하겠네요.
여기서 (5)번을 TDZ(Temporal Dead Zone) 이라고 합니다.

전역 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: [{ sayWow: Function }, 'sayYeah'],
  },
  scopeChain: ['전역 변수객체'],
  this: window,
}

TDZ 란?

변수를 선언 및 초기화 하기전에 호출하여 나타나는 사각지대 의 개념이다.


클로져란 ?

  • 클로져는 함수를 지칭하고 , 그 함수가 선언된 환경과의 관계라는 개념이 합쳐진것이다.
  • 클로져를 말할땐, 스코프/컨텍스트/비공개 변수와 함수의 관계를 항상 같이 말해주어야한다.
let makeClosure = function() {
  let name = 'zero';
  return function () {
    console.log(name);
  }
};
let closure = makeClosure(); // function () { console.log(name); }
closure(); // 'zero';

closure 함수 안에 console.log(name)이 있는데요.
name은 closure 함수의 매개변수도 아니고, closure 함수 내부에서 생성한 변수도 아닙니다.
바로 이런 것이 비공개 변수입니다.
function() { console.log(name) }은 name 변수나, name 변수가 있는 스코프에 대해 클로저라고 부를 수 있습니다.

클로져는 실전에서 겪어보면서 배우는게 제일 빠를듯 합니다.

profile
매일 1% 이상 씩 성장하기

0개의 댓글