1. 전역 문맥에서의 this

this의 첫 번째 동작 방식은 전역 객체를 참조하는 것이다.

  • Node 환경에서는 global객체

    NodeThis

  • 브라우저 환경에서는 window객체

    BrowserThis

    console.log(this === window); // ture
    
    var hoisting = 1;
    console.log(this.hoisting); // 1
    console.log(window.hoisting); // 1
    
    window.a = 5;
    console.log(this.a); // 5
    
    this.b = 10;
    console.log(window.b); // 10
    

2. 함수 문맥에서의 this

함수 내부에서 this는 호출 방식에 의해 결정된다.

1) 단순 호출

  • 단순히 함수를 호출할 경우 this의 값이 결정되지 않는다. 따라서 this는 전역객체를 참조한다.

    function f1() {
      return this;
    }
    const f2 = () => {
      return this;
    };
    console.log(f1() === window); // true
    console.log(f2() === window); // true
    

2) bind 함수 사용 (명시적 바인딩)

  • Function.prototype.bind를 사용하여 bind할 경우 this는 bind()의 첫 번째 매개변수이다.

    function func() {
      return this;
    }
    const bindFunc = func.bind({ name: "Early Hail" });
    console.log(bindFunc()); // { name: "Early Hail" }
    

3) 화살표 함수

  • 화살표 함수에서 this는 선언된 부분의 this context를 사용한다.

    암시적 바인딩이 발생하지 않는다.

    const obj = {
      arrowFunc: () => this,
      func: function () {
        return this;
      },
    };
    console.log(obj.arrowFunc() === window); // true
    console.log(obj.func() === window); // false
    

    코드 상으로 arrowFunc가 선언된 부분은 obj라고 생각할 수 있지만 obj객체가 만들어 질 때의 this는 window 객체이므로 선언된 부분의 this는 window이다. (this가 obj로 바인딩되지 않음)

  • 화살표 함수에서 this는 bind()에 의해 변경되지 않는다. (call, apply 포함)

    const func = () => {
      return this;
    };
    const bindFunc = func.bind({ name: "Early Hail" });
    console.log(bindFunc() === window);
    

4) 객체의 메소드

함수가 객체의 메소드로 호출될 때 해당 함수의 this는 객체를 가르킨다. (암시적 바인딩)

var a = 10;
const obj = {
  a: 100,
  arrowFunc: () => this.a,
  func: function () {
    return this.a;
  },
};
console.log(obj.arrowFunc()); // 10, this는 window
console.log(obj.func()); // 100, this는 obj

Arrow Function의 경우 암시적 바인딩이 발생하지 않으므로 this는 window이다.

var a = 10;
const obj = {
  a: 100,
  func: function () {
    return this.a;
  },
};
const globalFunc = obj.func;
console.log(globalFunc()); // 10, this는 window

obj.arrowFunc는 객체의 메소드이다.

하지만 obj를 통해 호출된것이 아닌 전역 객체에서 func를 호출한 것이므로 this는 window이다.

생성자로서의 this

함수를 new 키워드와 함께 생성자로 사용하면 this는 새로 생긴 객체에 바인딩된다.

class문법에서의 this도 해당 객체에 바인딩된다.