자바스크립트 / this 바인딩의 5가지 패턴 정리 (메소드 호출, call, apply ...)
Code/JavaScript

자바스크립트 / this 바인딩의 5가지 패턴 정리 (메소드 호출, call, apply ...)

반응형

 

아직도 코린이지만 정말 배운 지 얼마 안 된 코코코린이 시절에 this를 처음 접했을 땐 당최;; call ? apply? 생성자? 응? 머리에 남는 게 없었다. 그러다 과제를 계속 진행하면서 실제로 this를 사용하고 구체화시키면서 this에 대한 감이 조금은 잡혔으나, 개념적으로 부족한 부분이 있는지 되짚어보고자 오늘은 this에 대해 포스팅을 하려고 한다.

 

우선 자바스크립트의 경우에는 this가 명확하게 딱 이것이다!로 정의되어 있는 것이 아니다.

사용 패턴에 따라 바인딩 되는 this가 다르다는 것을 알고있어야 한다. 

 

 

Execution Context

 

자바스크립트 내에서 함수를 실행 시 execution context 마다 this가 생성된다.

이때의 this는 함수를 실행 할 때 호출 방법에 따라 바인딩되는 this 가 정해진다.

 

콘솔창 내 this 객체 확인

this 바인딩의 5가지 패턴

  • Global : window
  • Function : window
  • Method 호출 : 부모 object
  • Construction mode (new 연산자로 생성된 function 영역의 this) : 새로 생성된 객체
  • .call / .apply 호출 : call, apply 호출 시 첫번째 인자로 전달된 객체

 

1.  Global  :  window

window 객체

 

초기 글로벌 영역에서의 this는 window 객체 임을 확인할 수 있다.

 

그럼 전역 영역에 var 키워드를 사용하여 변수를 선언했을 경우 어떻게 될까?

 

 

var 키워드는 전역 영역, 즉 글로벌 스코프로 변수를 선언한다. 이경우 변수 a의 this는 window가 된다.

 

그럼 a면 a이고, this면 그냥 this이지 굳이 왜 this.a 마냥 dot이 붙어있는 건지 바로 와 닿지 않을 수 있다. 

 

window 객체

 

위와 같이 window 객체를 다시 한 번 조회해보면 전역 변수 a가 윈도우 객체의 속성으로 명시되어 있는 것을 확인할 수 있다. 

 

window가 객체!!!!라는 것을 안다면 이해하는 데 도움이 될 것 같다.

 

var a = 'tired';

console.log(this.a) // 'tired';
console.log(this) // Window 객체 ~

 

2.  Function  :  window

 

var a = 'tired';

function tempA() {
  function tempB() {
    function tempC() {
      console.log(this) // window 객체
      console.log(this.a) // 'tired'
    }

    tempC();
  }

  tempB();
}

tempA();

 

함수 내 내장함수가 아무리 많아도 함수에서의 this는 전역 영역. window 객체임으로 위에서 소개한 global과 동일한 성질이다.

 

3.  Method 호출 : 부모 object

 

method 호출은 객체.메소드() 와 같이 객체 내에 있는 함수(메소드)를 호출하는 방법이다. 

 

메소드 호출에서의 this는 왼쪽 부모 객체이다.

간단하게 말하자면 메소드 호출 앞에 있는 객체가 this라고 생각하면 된다. 

var a = {
  val : 0,
  increment: function() {
    this.val++;
  }
}

console.log(a); // {val: 0, increment: ƒ}

a.increment(); // Method 호출, this === a 

console.log(a); // {val: 1, increment: ƒ}

 

위 코드와 같이 메소드 호출 시 앞에 있는 부모 a객체가 this로 바인딩된다.

 

4.  Construction mode (new 연산자로 생성된 function 영역의 this) : 새로 생성된 객체

 

function People(name) {
  this.name = name;
}

//새 인스턴스 만들기
let people = new People('deemmun');

console.log(people.name); // 'deemmun'
console.log(name) // ReferenceError

 

new 연산자를 이용하여 새 인스턴스를 만드는 과정 중 함수 construtcor People 내 사용된 this는 people 객체가 this로 바인딩된다.

 

인스턴스 people, 인스턴스에서 this를 참조하고 있는 것이고, 그냥 name을 콘솔에 출력할 경우 전역 영역에 name이 없는 상태이기 때문에 참조 오류가 발생한다.

 

 5.  .call / .apply 호출  :  call, apply 호출 시 첫번째 인자로 전달된 객체

 

call, apply 메소드를 호출하는 경우는 this를 명시적으로 지정하고 싶을 때 사용한다.

첫 번째 인자가 this로 지정된다는 점을 유의하면 된다.

 

call 메소드를 활용하여 string prototype split 메소드 사용

call과 apply의 차이점은 전달 인자가 많을 경우 apply의 매개변수가 array의 형태로 들어가게 작성을 한다.

 

위의 코드에서의 this가  'I Love I-U' 로 지정되며, this에서 string.prototype.split 이 작동된 것이다.

 

반응형