자바스크립트의 this

최익·2023년 11월 2일
1

JS

목록 보기
2/2
post-thumbnail

자바스크립트의 this란?

객체는 상태를 의미하는 프로퍼티와 동작을 의미하는 메서드로 이루어져 있으며, 메서드는 객체의 상태를 참조 및 변경할 수 있어야합니다.

그렇다면 객체에서 자주 보이고 쓰이는 this란 무엇일까?

this란 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기참조 변수입니다. 즉, 자신이 속한 객체, 생성할 인스턴스의 프로퍼티 or 메소드를 참조하며 this는 함수 호출에 의해 동적으로 결정됩니다.

📢 함수의 호출 방식으로는

  1. 일반 함수 호출

  2. 메서드 호출

  3. 생성자 함수 호출

  4. apply, call, bind 함수에 의한 호출

총 4가지 방법이 있으며,

일반 함수로 호출한 this는 전역 객체를 가리키고, 콜백 함수도 전역 객체를 가리키게되고

메소드 함수의 내부 함수를 호출한다면 this가 전역객체를 가리키며, 메소드 함수를 호출한다면 메소드 함수의 this는 호출한 객체를 가리키게되고,

생성자 함수를 호출하면 this는 해당 함수를 가리키게되며,

aplly, call, bind는 인수로 전달한 객체를 호출당한 함수의 this가 가리키게됩니다.

📌 여기까지는 일단 가볍게 알아보고, 이어서 bind에 대해 한번 자세하게 알아보자!

먼자 bind에 대해 알아보기전 밑의 코드를 보자.

const obj = {
  someProperty: "Hello, World!",
  count: function () {
    console.log(this.someProperty);

    const nestedFunction1 = function () {
      console.log(this.someProperty);

      const nestedFunction2 = function () {
        console.log(this.someProperty);

        const nestedFunction3 = function () {
          console.log(this.someProperty);

          const nestedFunction4 = function () {
            console.log(this.someProperty);

            const nestedFunction5 = function () {
              console.log(this.someProperty);
            };
            nestedFunction5();
          };
          nestedFunction4();
        };
        nestedFunction3();
      };
      nestedFunction2();
    };
    nestedFunction1();
  },
};

obj.count();

위 코드를 실행하면 첫번째 출력만 someProperty를 가리켜 "Hello World"를 출력하게 되고 나머지는 undefined를 출력하게 된다.(undefined를 출력하게되는 이유는 메소드내의 함수를 일반 함수로 호출했기 때문)

그렇다면 메소드 내부의 함수들이 obj의 프로퍼티인 someProperty를 가리키게 하려면 어떻게 해야할까?

방법은 다음과 같다.

const obj = {
  someProperty: "Hello, World!",
  count: function () {
    console.log(this.someProperty);

    const nestedFunction1 = function () {
      console.log(this.someProperty);

      const nestedFunction2 = function () {
        console.log(this.someProperty);

        const nestedFunction3 = function () {
          console.log(this.someProperty);

          const nestedFunction4 = function () {
            console.log(this.someProperty);

            const nestedFunction5 = function () {
              console.log(this.someProperty);
            };
            nestedFunction5.bind(this)().;
          };
          nestedFunction4.bind(this)();
        };
        nestedFunction3.bind(this)();
      };
      nestedFunction2.bind(this)();
    };
    nestedFunction1.bind(this)();
  },
};

obj.count();

위 코드를 실행하면 모든 출력이 "Hello World!"가 나온다. bind 함수가 전달해준 this가 대체 뭐길래 모두 같은 obj의 someProperty를 가리키게 되는 걸까?

혹시 bind 함수가 바인딩 시켜준 this가 그냥 당연하게 obj를 가리키게 된다고 생각하는 분들이 계실 수 있다.

물론 결론적으로는 모든 this들이 obj를 가리켜 같은 출력값이 나오기는하지만.. 한번 더 고민해볼 필요가 있다. 이는 어떻게 보면 당연한게 아닐수도.. ㅎ

우선 bind함수의 this는 바인드가 실행되는 시점을 가리킨다.

즉, nestedFunction1에 바인딩된 this는 count 함수 블록에서 생성되었기 때문에 메소드 함수로 생성된 count가 가리키는 this는 obj이기 때문에 바인딩된 this도 obj를 가리키게된다.

그렇다면 nestedFunction2에 바인딩된 this는..?

이때 생성된 this는 nestedFunction1 함수 블록에서 생성이 되었고, nestedFunction1 함수의 this가 가리키는 곳은 count를 가리키고, count의 this는 obj를 가리키기 때문에 체이닝이되어 nestedFunction2 함수의 this도 obj를 가리키게된다.

이렇게 나머지 일반함수들에 바인딩된 this도 체이닝이되어 결국 같은 곳인 obj를 바라보게 되는 것!

당연하게 생각할 수 있는 부분이지만 파보면 결국 원리가 있었다는..!

앞으로도 공부를 하면서 의구심이 드는 부분이 있다면 계속 파고 들어봐야겠다. 그리고 오늘 데브코스 석주님의 발표를 보면서 꾸준하게 학습한 내용을 기록해야겠다는 생각이 들었고, 단순 기록이 아닌 왜?라는 의구심과 2뎁스까지 고민한 흔적, 문제 상황과 해결과정에 대한 기록을 열심히 그리고 '잘' 해야겠다고 느꼈다.

profile
https://choi-ik.tistory.com/ 👈🏻 여기로 블로그 이전했습니다 ㅎ

0개의 댓글