# this

this란 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다. 자바스크립트 엔진에 의해 암묵적으로 생성되며 객체의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이므로 일반적으로 객체의 메서드 내부 또는 생성자 함수 내부에서만 의미가 있다.

# 전역객체

console.log(this); // Window

var ga = 'Global variable';

console.log(ga); // Global variable
console.log(window.ga); // Global variable

function foo() {
  console.log('invoked!');
}
window.foo(); // invoked!

전역객체는 모든 객체의 유일한 최상위 객체를 의미하며 일반적으로 Browser-side에서는 window, Server-side(Node.js)에서는 global 객체를 의미한다.

또한, 전역객체는 전역 스코프를 갖는 전역변수를 프로퍼티로 소유한다. 글로벌 영역에 선언한 함수는 전역객체의 프로퍼티로 접근할 수 있는 전역 변수의 메소드이다.

# 함수의 this

function aOuter(){
    console.log(this); // Window, strict모드 시 undefined

    function aInner() {
        console.log(this); // Window, strict모드 시 undefined
    }
    aInner();
}
aOuter();

기본적으로 this는 전역객체(Global object)에 바인딩된다. 전역함수는 물론이고 심지어 내부함수의 경우도 this는 외부함수가 아닌 전역객체에 바인딩된다.

var value = 1;

var obj = {
  value: 100,
  foo: function() {
    setTimeout(function() {
      console.log("3. 콜백함수: ",  this);  // window
    }, 0);
  }
};

obj.foo();

콜백함수의 경우에도 this는 전역객체에 바인딩된다.

내부함수는 일반 함수, 메소드, 콜백함수 어디에서 선언되었든 관계없이 this는 전역객체를 바인딩한다.

# 객체의 메소드 this

객체의 프로퍼티의 value값이 함수일 경우 메서드라고 한다.

var obj = {
    a: function() { // 객체의 메서드(일반함수)
        var that = this;
        console.log(this); // {a: ƒ, b: ƒ}

        function aInner() { // 객체의 메서드(일반함수)의 내부함수
            console.log(this); // Window
            console.log(that); // {a: ƒ, b: ƒ}
        }
        aInner();
    },
    b: () => { // 객체의 메서드(화살표함수)
        console.log(this); // window

        function bInner() { // 객체의 메서드(화살표함수)의 내부함수
            console.log(this); // Window
        }
        bInner();
    }
  };

obj.a();
obj.b();

// 객체의 메소드를 새로운 변수에 할당하는 경우
var a2 = obj.a;
a2(); // window
window.a2() // window

위와 같이 메서드 내부에 새로운 변수 that에 this를 할당하여 메서드의 내부 함수가 전역객체에 바인딩되는 것을 막을 수 있다. aInner함수에 메서드 내부에 생성한 that을 활용한다.