본문 바로가기
JavaScript

[JavaScript]객체의 메서드에 this를 쓸때 헷갈리는 동작

by hotdog7778 2023. 8. 29.

 

 

1. 기본 동작

JavaScript에서 객체의 메서드는 메서드가 속한 객체에 바인딩된 this 값을 가지게 됩니다. 그러나 객체의 메서드를 콜백 함수로 사용하는 과정에서 this의 값이 예상과 다르게 변할 수 있는데요. 이러한 현상은 주로 함수의 호출 방식에 기인합니다.

 

아래 예시를 통해 살펴보겠습니다.

const obj = {
  method: function () {
    console.log(this);
  },
};

obj.method(); // obj

위 코드에서 obj.method()를 호출하면, 메서드 내부의 this는 obj 객체에 바인딩되어 메서드가 속한 객체인 obj가 출력됩니다.

 

 

2. this를 사용하는 메서드를 다른 함수에 콜백으로 넘겼을 때

근데 아래 코드처럼 obj.method를 사용했을때, this가 이전과 다르게 출력됩니다.

function runCallback(callback) {
  callback();
}

runCallback(obj.method); // 전역 객체 (브라우저: window, Node.js: global)
	          // 실제로는 window는 전역객체를 참조해서 전역객체처럼 동작하는것 입니다.

콜백함수로 obj.method 를 넘겨주고 그걸 실행하는 함수를 만들어서

실행시켜 보니 여기서는 this가 global 객체라고 찍힙니다.

왜냐면 runCallback 함수에서는 obj.method() 형태로

실행시키는 것이 아니라 method() 형태로 실행시키기 때문입니다.

 

이는 obj.method()는 method()를 참조하는 값을 복제해서

callback이란 변수에 넣어 사용하기 때문입니다. 아래와 같습니다.

  • obj.method —참조—> method()
  • callback —참조—> method()

 

obj.method()과 callback() 둘 다 method()를 실행시키는 것이지만 차이점은

  1. obj.method()에서는 함수를 호출할 때 오브젝트를 명시해 주었고
  2. callback()에서는 함수를 호출할 때 오브젝트를 명시해 주지 않았습니다.

1번에서는 함수호출시 오브젝트를 명시해 주어서 this가 obj에 바인딩되었습니다.

반면에 오브젝트를 명시해주지 않은 2번에서는 this가 글로벌 오브젝트에 바인딩됩니다.

 

 

참고자료.

https://velog.io/@marulloc/Execution-Context-6-This와-This-Binding 

이 포스팅에서 ‘3.3 this가 참조하는 오브젝트‘ 를 보면 이해에 도움이 많이 됩니다.

 

 

3. 이런 경우에 obj 객체에 this를 바인딩하고 싶다면.

 

- bind 메서드를 사용한 명시적 바인딩:

runCallback(obj.method.bind(obj)); // obj

 

 - 화살표 함수를 활용 :

runCallback(() => obj.method()); // obj