대부분의 객체지향 언어에서 this는 클래스로 생성한 인스턴스 객체를 의미한다. 클래스에서만 사용할 수 있기 때문에 혼란의 여지가 많지 않지만, this는 자바스크립트의 어디서든 사용할 수 있다.
this는 상황에 따라 바라보는 대상이 달라지게 되는데, 어떤 이유로 그렇게 되는지 파악하기 위해서는 정확한 작동 방식을 이해해야 한다.
this는 함수를 호출할 때 결정된다. 즉 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라지는 것.
전역 공간에서 this는 전역 컨텍스트를 생성하는 주체가 전역 객체이기 때문에 전역 객체를 가리킨다.
브라우저 환경에서는 window, Node.js에서는 global이다.
전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다.
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
그런데 '삭제'명령에서는 전역변수 선언과 전역객체의 프로퍼티 할당 사이가 전혀 다른데, 이는 사용자가 의도치 않게 삭제하는 것을 방지하는 차원에서 마련한 방어전략이라고 볼 수 있다. 즉 전역변수를 선언하면 자바스크립트 엔진이 이를 자동으로 전역객체의 프로퍼티로 할당하면서 추가적으로 해당 프로퍼티의 configurable 속성(변경 및 삭제 가능성)을 false로 정의하는 것이다.
함수 내부에서의 this
어떤 함수를 함수로서 호출할 경우 호출 주체를 명시하지 않고 개발자가 코드에 직접 관여해서 실행한 것이기 때문에 호출 주체를 알 수 없어서 this가 지정되지 않는다. 따라서 함수에서의 this는 전역객체를 가리킨다.
메서드의 내부함수에서의 this
this바인딩에 관해서는 함수를 실행하는 당시의 주변환경(메서드 내부인지, 함수 내부인지 등)은 중요하지 않고, 오직 해당 함수를 호출하는 구문 앞에 점 또는 대괄호 표기가 있는지 없는지가 관건이다.
메서드의 내부 함수에서의 this를 우회하는 방법
변수를 활용하여 우회할 수 있다. 예를들어서
var obj = {
outer: function () {
console.log(this); // (1) {outer: f }
var innerFunc1 = function () {
console.log(this); // (2) Window { ... }
};
innerFunc1();
var self = this;
var innerFunc2 = function () {
console.log(self); // (3) {outer: f }
};
innerFunc2();
}
};
obj.outer();