본문 바로가기
Front-End/JavaScript

this

by 연제원 2021. 1. 12.

✅ this란?

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

모든 함수는 실행할 때마다 this라는 객체가 추가된다. arguments 객체와 함께 함수 내부로 암묵적으로 전달되는 것이다.

 

아무리 봐도 딱 한줄로 정의하기가 너무 어렵다. 이 말은 공부가 덜 되었다는 뜻! 우선 의식의 흐름대로 정리해보려고 한다.

 


함수 실행의 다섯가지 방법

함수 실행에는 다섯 가지 방법이 있다. 이때 this에게 있어서, '함수가 무엇인지?'가 중요한 것이 아니라, '어떻게 실행(호출)되는 것인지?'가 중요하기 때문에 함수 실행의 다섯가지 방법을 보도록 하자.

1. Global
// 엄밀히 말하면 함수 실행은 아니고, 전역에서 this를 참조할 때를 의미
console.log(this)

2. Funtion 호출
foo()

3. Method 호출
obj.foo()

4. new 키워드를 이용한 생성자 호출
new Foo()

5. .call 또는 .apply 호출
foo.call()
foo.apply()

 

이렇게 다섯가지의 함수 호출 방법이 있으니, 각 호출 방법에 따라 this가 뜻하는 바는 달라질 것이다. 앞에서 this함수 실행시 호출(invocation) 방법에 의해 결정되는 특별한 객체라고 했다. 즉 함수 실행방법에 따라 this가  참조하는(지목하는, 가리키는 혹은 뜻하는) 객체가 지정된다는 말이다. 이를 바인딩 패턴이라고 한다.

 

계속 강조하지만 기억하자!

this는 함수가 호출되는 방법(호출 패턴)에 따라 다른 객체를 참조(this 바인딩)하게 된다!!!

 


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

우선, Global, Function 호출은 애초에 this를  사용하지 않는 것을 권한다고 한다. 그 이유는 별 쓸모가 없어서 그렇지 않을까?

그래서 중요하지 않다고 생각하고 간략하게 어떤 객체가 바인딩 되는지만 볼 것이다.


1. Global

바인딩되는 객체(브라우저) = window (strict mode에서는 undefined)
바인딩되는 객체(node.js) = module.exports

2. Function 호출

바인딩되는 객체(브라우저) = window (strict mode에서는 undefined)
바인딩되는 객체(node.js) = global

(module.exports가 뭔지는 더욱 자세한 공부 후에 정리할 것!)

간략하게 말하자면 Global, Funtion 호출은 제일 밖에 있는? 최상단에 있는 window, global객체를 참조한다! 그래서 결국 쓸 일이 없다.

 

추가로, 화살표 함수에서도 this를 사용할 생각을 하지 말 것!


그럼 나머지 3가지가 중요하다는 뜻이다.

3. Method 호출

바인딩되는 객체 = 부모 객체 (실행 시점에 온점(.) 왼쪽에 있는 객체)

 

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

메소드란?
입력값이 있고, 그 입력값을 받아서 무언가 한 다음 결과를 도출해 내는 수학의 함수와 비슷한 개념
즉, 메소드 = 함수

그럼 객체 내에 메소드를 호출하는 방법이라는 말은, 객체 내에 있는 키-값쌍이 있는데 이 값(프로퍼티 = 함수)을 불러낸다는 말인 것이다. 예시를 보자.

let obj = {
  value: 0,
  increase: function() {
    this.value++
  },
  decrease: function() {
    this.value--
  },
  getValue: function() {
    return this.value
  }
}

obj.increase()
obj.increase()
obj.increase()
obj.decrease()
obj.getValue() // ?

obj는 현재 내가 지정한 객체다. obj.increase()가 뜻하는 바는 obj의 키(increase라는 함수)를 실행(())이라는 말이다.

 

다시 정리해보면

메소드 호출 =객체 내(obj)에 있는 값(프로퍼티=increase라는 함수)을 불러낸다(실행) = obj.increase()

바인딩되는 객체 = 부모 객체(실행 시점에 온점 왼쪽에 있는 객체) = obj

this가 참조하는 객체는?! 바로 obj 즉, 부모 객체다.

그렇다면 obj.increase() 가 실행이 될 때, this.value++ 는 obj.value++ 랑 같다는 것!

그래서 마지막 obj.getValue()this.value를 리턴 즉, obj.value를 리턴한다는 말이므로 2다!

 

사실 이렇게 해도 이해가 안될 수 있다. 나도 삽질을 엄청나게 했다. 바로 이해가 가는 법!

 

Function 호출 VS Method 호출

const obj = {
  test1: function() {
    return function() {
      return this
    }
  },
  test2: function() {
    return this
  }
}

obj.test1()() // ?
obj.test2()   // ?

obj.test1()()과 obj.test2()는 비슷해보이지만 아주 다르다.

이것만 이해하면 끝~!


4.  new 키워드를 이용한 생성자 호출

바인딩되는 객체 = 새롭게 생성된 인스턴스 객체

new 연산자 정의

 

'new' 연산자와 생성자 함수

 

ko.javascript.info


5. .call 또는 .apply 호출

바인딩되는 객체 = 첫번째 인자로 전달된 객체

✅ 정리

함수 호출(실행) 방법 this가 참조하는 객체 (바인딩되는 객체)
Global 브라우저 = window
node.js = module.exports
Function 호출 브라우저 = window
node.js = global
Method 호출 부모 객체
new키워드 생성자 호출 새롭게 생성된 인스턴스 객체
.call 또는 .apply 호출 첫 번째 인자로 전달된 객체

 

'Front-End > JavaScript' 카테고리의 다른 글

프로토타입(Prototype) 이해하기(2)  (0) 2021.01.15
프로토타입(Prototype) 이해하기(1)  (0) 2021.01.15
ES6 문법  (0) 2021.01.09
명령형 VS 선언형 프로그래밍  (0) 2021.01.08
고차 함수_3 (feat. 추상화)  (0) 2021.01.08

댓글