this 키워드

Yun Hyuk Ko·2021년 2월 11일
0

this 키워드

목록 보기
1/1

this는 함수 실행시 호출(invocation) 방법에 의해 결정되는 특별한 객체이다.
함수 실행시 결정되므로, 실행되는 맥락(execution context)에 따라 this는 다르게 결정된다.

함수 실행의 다섯가지 방법

함수가 무엇이냐가 중요한 것이 아니라, 어떻게 실행되는 것인지가 중요하다.
함수 실행의 다섯가지 방법을 소개해본다.

  1. Global: 정확히 말하면 함수 실행은 아니고, 전역에서 this를 참조할 때를 의미한다.
console.log(this)
  1. Function 호출
foo()
  1. Method 호출
obj.foo()
  1. new 키워드를 이용한 생성자 호출
new Foo()
  1. .call 또는 .apply 호출
foo.call()
foo.apply()

함수 실행에 따른 this 바인딩 패턴

이 함수 실행의 다섯가지 방법에 따라 this 역시 다섯가지 바인딩 패턴이 존재 하는데, 그 중 아래 세가지 형태는 반드시 기억해야 한다.

1번 Global 형태의 사용이나, 2번의 Function 호출 방법을 통해 함수를 실행할 경우에는, 애초에 this를 사용하지 않는 것을 권장한다. Function 호출시 this를 사용할 이유는 없다. 흔히 사용하지 않는 방법이다. 1,2번 방법의 함수 호출시, 다음과 같이 경우에 따라 바인딩이 다양하게 달라진다. 아래 내용은 굳이 기억할 필요는 없으며, 애초에 사용하지 않으면 된다.

Method 호출

메소드 호출은 객체.메소드() 과 같이 객체 내에 메소드를 호출하는 방법을 의미한다.

단순 객체를 사용한 Singleton 패턴에서 이러한 예제를 흔히 볼 수 있다. 다음은 카운터를 구현한 예제이다.

let counter1 = {
  value: 0,
  increase: function() {
    this.value++ // 메소드 호출을 할 경우, this는 counter1을 가리킵니다
  },
  decrease: function() {
    this.value--
  },
  getValue: function() {
    return this.value
  }
}

counter1.increase()
counter1.increase()
counter1.increase()
counter1.decrease()
counter1.getValue() // 2

Singleton 패턴은 단 하나의 객체만 만들 수 있으므로, 똑같은 기능을 하는 카운터를 여러 개 만드려면, 아래 예제 코드와 같이 클로저 모듈 패턴을 이용하거나, 클래스로 만들어서 생성자 호출과 같이 사용할 수 있다.

function makeCounter() {
  return {
    value: 0,
    increase: function() {
      this.value++ // 메소드 호출을 할 경우, this는 makeCounter 함수가 리턴하는 익명의 객체입니다
    },
    decrease: function() {
      this.value--
    },
    getValue: function() {
      return this.value;
    }
  }
}

let counter1 = makeCounter()
counter1.increase()
counter1.getValue() // 1

let counter2 = makeCounter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2

생성자 호출

생성자 호출은 객체.메소드() 과 같이 객체 내에 메소드를 호출하는 방법과 비슷하지만, 객체가 new 키워드를 이용해서 만들어졌다는 것이 다르다.
이 때의 객체는 우리가 인스턴스라고 부른다. 즉, 인스턴스.메소드() 의 형태의 호출이다.

카운터를 클래스로 만들어보자.

class Counter {
  constructor() {
    this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스입니다
  }
  increase() {
    this.value++
  }
  decrease() {
    this.value--
  }
  getValue() {
    return this.value
  }
}

let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1
profile
기억보다 좋은건 기록이다

0개의 댓글