자바스크립트에서 this는 실행 컨텍스트가 생성될 때 결정된다. 실행 컨텍스트는 함수를 호출할 때 생성되므로 this는 함수를 호출 할 때 결정된다라고 할 수 있다.
전역 공간에서 this는 전역 객체를 가리킵니다.
전역 객체는 자바스크립트 런타임 환경에 따라 다른 이름과 정보를 가지고 있다. 브라우저에서는 window, Node.js 환경에서는 global이다.
코드로 알아보자
var a = 1;
console.log(a); // 1
console.log(this.a); // 1
console.log(window.a); // 1
모두 1이 출력된다. 이는 전역 컨텍스트 Lexical 환경에서 environmentRecord(Declare, Object)에 ObjectBinding할당 되고 이로인해, 전역 객체(window)에 할당 되기 때문이다.
정확히 표현하자면 전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다.
함수를 실행하는 데 여러가지 방법 중 가장 일반적인 2가지 방법을 알아보자.
함수로 호출하는 경우, 메서드로서 호출하는 경우이다. 이 둘을 구분하는 유일한 차이는 독립성에 있다.
this에는 호출한 주체에 대한 정보가 담긴다. 함수명(프로퍼티) 앞의 객체가 호출 주체이다.
var obj = {
method: function(x) { console.log(this, x); }
};
obj.method(1); // {method: f} 1
obj['method'](2); // {mehod: f} 2
// this === obj -> true
어떤 함수를 함수로서 호출할 경우 this를 지정하지 않는다. 그래서 this는 전역 객체를 가리킨다.
함수로서 호출했는지, 메서드로서 호출했는지만 잘 파악하면 this의 값을 정확히 맞출 수 있다.
var obj = {
outer: function() {
console.log(this); //(1)
var innerFunc = function () {
console.log(this); //(2) (3)
}
innerFunc();
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod();
}
};
obj1.outer();
해당 함수를 실행할 경우 (1): obj1, (2): 전역객체(window), (3): obj2이다.
1번은 obj1.outer() 의 실행 으로 인해 this가 출력된다. outer함수 앞에 호출객체는 obj1이므로 this는 obj1이다.
2번은 obj객체 내부에서 innerFunc(); 을 통해서 실행되는데 이때 innerFunc 함수의 호출 주체는 없으므로 함수로서 호출이 된 경우이다. 따라서 this는 전역객체(window)가 된다.
3번은 obj2.innerMethod(); 를 통해 실행되고 함수의 호출 주체가 obj2이므로 this는 obj2가 된다.