실행 컨텍스트는 자바스크립트 코드가 실행되는 환경이다.
코드에서 참조하는 변수, 객체(함수 포함), this등에 대한 레퍼런스가 있다.
실행 컨텍스트는 전역에서 시작해, 함수가 호출될 때 스택에 쌓이게 된다.
중요한 점은 실행 컨텍스트에 이름에 맞게 함수가 실행이 될 때 문맥이 만들어 진다.
let a = 10;
function f1() {
let b = 20
function print(v) { console.log(v) }
function f2() {
let c = 30
print(a + b + c)
}
f2();
}
f1();
'전역 컨텍스트': { '변수 객체': { arguments: null, variable: [ { 'a': 10 }, { 'f1': function } ] }, scopeChain: ['전역 변수 객체'], this: window }
'f1 컨텍스트': { '변수 객체': { arguments: null, variable: [ { 'b': 20 }, { 'print': function }, { 'f2': function } ] }, scopeChain: ['전역 변수 객체', 'f1변수 객체'], this: window }
'f2 컨텍스트': { '변수 객체': { arguments: null, variable: [ { 'c': 30 } ] }, scopeChain: ['전역 변수 객체', 'f1변수 객체', 'f2변수 객체'], this: window }
'print 컨텍스트': { '변수 객체': { arguments: [{ v: 60 }], variable: null }, scopeChain: ['전역 변수 객체', 'f1변수 객체', 'f2변수 객체', 'print변수 객체'], this: window }
const obj = { name: "seo", sayName: function() { console.log("sayName: ", this); function inner1() { console.log("inner1: ", this); } const inner2 = () => { console.log("inner2: ", this); } function bindedInner() { console.log("bindedInner: ", this) } inner1(); inner2(); bindedInner.bind(obj)(); }, sayName2: () => { console.log("sayName2: ", this); function inner3() { console.log("inner3: ", this); } const inner4 = () => { console.log("inner4: ", this); } inner3(); inner4(); } } obj.sayName(); obj.sayName2(); const sayN = obj.sayName; const sayN2 = obj.sayName2; sayN(); sayN2();
callstack - (설명의 편의를 위해 함수가 끝난후 스택을 지우지는 않았음)
inner4() -> this: window(화살표 함수 이므로 부모인 sayN2의 this)
inner3() -> this: window
sayN2() -> this: window
bindedInner() -> this: obj(일반함수에서 bind, call, apply를 해주면 this를 명시할 수 있다.)
inner2() -> this: window(화살표 함수 이므로 부모인 sayN의 this)
inner1() -> this: window
sayN() -> this: window
inner4() -> this: window(화살표 함수이므로 부모인 sayName2의 this)
inner3() -> this: window
obj.sayName2() -> this: window(화살표 함수이므로 부모인 anonymous의 this)
bindedInner() -> this: obj(일반함수에서 bind, call, apply를 해주면 this를 명시할 수 있다.)
inner2() -> this: obj (화살표 함수의 this 부모의 this 그러므로 부모인 sayName의 this)
inner1() -> this: window
obj.sayName() -> this: obj (객체로 부터 호출 일반함수의 this는 자신을 호출한 객체)
anonymous -> this: window