실행 컨텍스트는 자바스크립트가 어떻게 동작하는지 설명 해준다.
예시코드
var name = 'kyusik';
function wow(word) {
console.log(word + ' ' + name);
}
function say () {
var name = 'gyusiki';
console.log(name);
wow('hello');
}
say();
흐름
- 일단 처음 실행하는 순간(브라우저가 자바스크립트를 로딩해서 실행하는 순간) 모든 것을 포함하는 전역 컨텍스트 가 생긴다.페이지가 종료될때까지 유지.
- 함수를 호출할때 마다 함수 컨텍스트가 하나씩 쌓인다.
컨텍스트의 원칙
- 일단 전역 컨텍스트를 하나 생성후, 함수 호출시 마다 컨텍스트가 하나씩 생긴다.
- 컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments, variable), scope chain, this 가 생성 된다.
- 컨텍스트 생성 후 함수가 실행되는데, 그 함수에 사용되는 변수들은 변수 객체 안에서 값을 찾고, 없으면 스코프 체인을 따라 올라가면서 찾습니다.
- 함수 실행이 마무리되면 해당 컨텍스트는 사라집니다.
- 페이지가 종료되면 전역 컨텍스트가 사라집니다.
전역 컨텍스트 ( 위의 코드 설명 )
- 맨 처음 자바스크립트가 실행되고 전역 컨텍스트가 생성된다.
- 컨텍스트안에 변수객체, scope chain, this가 들어간다.
- 변수객체에 arguments(함수 인자)는 없고, variable은 전역의 변수들입니다. 현재는 name, wow, say 가 있다.
- scope chain (자신과 상위 스코프들의 변수객체)는 자기 자신인 변수객체 이다.
- this는 따로 설정되어 있지 않으면 Window 이다.
- this는 new나 bind 같은 상황에서 바뀌게된다.
'전역 컨텍스트': {
변수객체: {
arguments: null,
variable: ['name', 'wow', 'say'],
},
scopeChain: ['전역 변수객체'],
this: window,
}
코드가 실행되게 되고.......
variable: [{ name: 'zero' }, { wow: Function }, { say: Function }]
wow랑 say는 호이스팅 때문에 선언과 동시에 대입이 됩니다.
함수 컨텍스트 생성 ( 위의 코드 설명 )
- 맨 마지막 줄에서 say();를 하는 순간
- 새로운 컨텍스트인 say 함수 컨텍스트가 생깁니다. (하지만 아까 생성된 전역 컨텍스트는 그대로 존재)
- 전역컨텍스트와 마찬가지로 say 컨텍스트도 변수객체, scope chain, this가 생성됩니다.
- 변수객체에 arguments는 없고, variable은 name 하나 뿐입니다.
- scope chain은 일단 자기 자신인 say 변수객체와 전역 변수객체 가 있습니다.
- this는 따로 설정해준 적이 없으니 window입니다.
'say 컨텍스트': {
변수객체: {
arguments: null,
variable: ['name'],
},
scopeChain: ['say 변수객체', '전역 변수객체'],
this: window,
}
say 함수 실행 ( 위의 코드 설명 )
- say를 호출한 후 (8)~(10)실행
- variable의 name에 "gyusiki"를 넣고
console.log(name)
을 실행.
- 여기서 name의 변수는 먼저 say 컨텍스트 안에서 찾습니다.
console.log(name)
의 name은 "gyusiki"이므로 gyusiki를 찍는다.
- 다음
wow('hello')
를 만나게되고 say 컨텍스트 안에서 wow 변수를 찾지만 wow의 변수는 없습니다.
- 그러면 scope chain을 따라 올라가 상위 변수객체에서 찾습니다.
- 전역 변수객체에 variable에 wow라는 함수가 있고 이것을 호출합니다.
wow 함수 컨텍스트 생성 ( 위의 코드 설명 )
- wow함수가 호출되고 wow 컨텍스트가 생긴다.
- 이번에 변수객체의 arguments는
{word : 'hello'}
이고 varialble은 없으니 null 입니다.
- scope chain은 자기자신인 wow 스코프와 전역 스코프입니다.
- 여기서 중요한 게 lexical scoping에 따라 wow 함수의 스코프 체인은 선언 시에 이미 정해져 있습니다.
- 즉 say 스코프는 wow 컨텍스트의 scope chain이 아닙니다.
'wow 컨텍스트': {
변수객체: {
arguments: [{ word : 'hello' }],
variable: null,
},
scopeChain: ['wow 변수객체', '전역 변수객체'],
this: window,
}
wow 함수 실행 ( 위의 코드 설명 )
- 이제 컨텍스트가 생겼고 함수가 실행됩니다.
- say 함수는 아직 종료된 게 아닙니다.
console.log(word + ' ' + name);
를 실행합니다.
- word랑 name 변수는 wow 컨텍스트에서 찾으시면 됩니다.
- word는 wow 스코프의 변수객체안의 arguments에서 찾을 수 있고, name은 wow 스코프에 없으므로 전역 변수객체로 올라갑니다.
- 전역 변수객체의 varilable의 name이 "kyusik"으로 되어있으니
console.log(word + ' ' + name);
는 hello kyusik이 됩니다.
- wow 컨텍스트에 따르면 wow 함수는 애초에 say 컨텍스트와 일절 관련이 없었던 겁니다.
나머지 함수 실행 ( 위의 코드 설명 )
- wow 함수가 종료되고, wow 컨텍스트가 사라집니다.
- say 함수의 실행도 마무리 됩니다. say 컨텍스트가 사라집니다.
- 전역 컨텍스트가 사라집니다.