this 키워드

feelslikemmmm·2020년 10월 20일
0

javascript

목록 보기
25/37
post-thumbnail

this 키워드


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 역시 다섯가지 바인딩 패턴이 존재합니다. 그 중 아래 세가지 형태는 반드시 기억해야 합니다.

패턴바인딩되는 객체설명
Method 호출부모 객체 (실행 시점에 온점 왼쪽에 있는 객체)하나의 객체에 값과 연관된 메소드를 묶어서 사용할 때 주로 사용함
new 키워드를 이용한 생성자 호출새롭게 생성된 인스턴스 객체객체 지향 프로그래밍에서 주로 사용함
.call 또는 .apply 호출첫번째 인자로 전달된 객체this 값을 특정할 때 사용하며, 특히 apply의 경우 배열의 엘리먼트를 풀어서 인자로 넘기고자 할 때 유용함

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

패턴바인딩되는 객체설명
Globalwindow (strict mode에서는 undefined)module.exports
Function 호출window (strict mode에서는 undefined)global

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개의 댓글