2019-05-18 Soma JS(1)
실행컨텍스트
- 실행컨텍스트 : JS가 왜 그렇게 동작하는지 설명해준다.
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)
//result
nero
hello zero
- wow(‘hello’)가 hello zero인 이유는 lexical scoping때문이다.
- 처음 코드를 실행(브라우저가 스크립트를 로딩해서 실행)하는 순간 모든 것을 포함하는 전역컨텍스트가 생긴다. 모든것을 관리하기 위한 환경이다. 이 전역컨테스트는 페이지가 종료될때까지 유지가 된다.
- 함수컨텍스트가 있는데, 함수를 호출할때마다 함수컨텍스트가 생긴다.
컨텍스트 4가지 원칙
- 전역컨텍스트 하나 생성후, 함수 호출 시마다 컨텍스트가 생긴다
- 컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments, variable), scope chain, this가 생성된다.
- 컨텍스트 생성 후 함수가 실행되는데, 사용되는 변수들은 변수객체에서 찾고, 없다면 스코프체인을 따라 올라간다.
- 함수 실행이 마무리가 되면 해당 컨텍스트는 사라진다.(클로저제외) 페이지가 종료되면 전역컨텍스트가 사라진다.
전역컨텍스트
- 전역컨텍스트가 생성후 변수객체, scope chain, this가 들어온다. 전역컨텍스트는 arguments(함수의인자)가 없다. variable은 해당 스코프의 변수들이다.
- scope chain은 자기자신인 전역변수객체이다.
- this는 따로 설정안하면 window
'전역 컨텍스트': {
변수객체: {
arguments: null,
variable: ['name', 'wow', 'say'],
},
scopeChain: ['전역 변수객체'],
this: window,
}
variable: [{ name: 'zero' }, { wow: Function }, { say: Function }]
- 호이스팅때문에 wow, say는 선언과 동시에 대입이 된다.
함수컨텍스트
- say()를 하는순간 새로운 컨텍스트인 say함수컨텍스트가 생성된다.
-
say()함수에 arguments가 없기때문에 null, variable은 name뿐이다.
``` ‘say 컨텍스트’: { 변수객체: { arguments: null, variable: [‘name’], // 초기화 후 [{ name: ‘nero’ }]가 됨 }, scopeChain: [‘say 변수객체’, ‘전역 변수객체’], this: window, }
- say()함수 내에서 wow()함수를 호출했으므로 wow컨텍스트가 생긴다. wow컨텍스트의 arguments는 word='hello'고, scope chain은 wow스코프와 전역스코프이다.
wow 컨텍스트’: { 변수객체: { arguments: [{ word : ‘hello’ }], variable: null, }, scopeChain: [‘wow 변수객체’, ‘전역 변수객체’], this: window, }
- wow함수가 실행되면 word는 arguments에서 찾을 수 있고, name은 wow변수객체에 값이 없으므로 scope chain을 따라 전역스코프에서 찾는다. lexical scoping에 의해 name은 zero이다.
## 호이스팅
- 호이스팅이란? 변수를 선언하고 초기화했을 때 선언부분이 최상단으로 끌어올려지는 현상이다.
- sayWow처럼 함수표현식이 아니라 함수선언식일 때는 식 자체가 통째로 끌어올려진다.
console.log(zero); sayWow();
function sayWow() { console.log(‘wow’); } var zero = ‘zero’; //result undefined wow
function sayWow() { console.log(‘wow’); } var zero; console.log(zero); sayWow(); zero = ‘zero’
- let zero = 'zero'로 선언을 하면 에러가 발생을 한다.
- 위의 코드는 호이스팅되면서 실제로는 밑의 코드처럼 작동을 한다.
### 함수선언식 호이스팅
sayWow(); // (3) sayYeah(); // (5) 여기서 대입되기 전에 호출해서 에러 var sayYeah = function() { // (1) 선언 (6) 대입 console.log(‘yeah’); } function sayWow() { // (2) 선언과 동시에 초기화(호이스팅) console.log(‘wow’); // (4) }
‘전역 컨텍스트’: { 변수객체: { arguments: null, variable: [{ sayWow: Function }, ‘sayYeah’], }, scopeChain: [‘전역 변수객체’], this: window, } ```
- 함수표현식으로 선언을 하면 에러가 발생을 한다.
- 처음 실행시에 전역컨텍스트가 생성이 되는데, sayWow함수는 함수 선언식이므로 컨텍스트 생성 후 바로 대입이 된다. 하지만 sayYeah는 대입되기전에 호출을 해서 에러가 발생한다.