[JavaScript] Is this "This?"

핫걸코더지망생·2023년 9월 19일
0

JavaScript

목록 보기
4/6
post-thumbnail

✅ This란?

💡 핵심 -> this의 값은 함수를 호출한 방법에 의해 결정되는 자기 참조 변수! 입니다. 그럼 각 상황별로 this가 어디에 바인딩되는지 알아보러 가보죠!
👉 바인딩? -> 식별자와 값을 연결하는 과정으로, this와 this가 가리킬 객체를 바인딩쓰



✅ This의 특징

📍 1. 전역공간에서의 this

🚗 car 라는 객체에 name과 getName이라는 정보를 담아 줍니다. 그리고
🚙 globalCar 라는 전역 변수를 생성해 준뒤, car.getName이라는 함수를 할당해 줘볼게요

 const car = {
      name: "KIA",
      getName: function () {
        console.log("car getName", this);
      },
    };

const globalCar = car.getName;
    globalCar();

이때 globalCar()을 호출하면 어떤 값이 찍힐까요? car 의 이름인 "KIA" 라는 값이 찍힐까요? 그렇지 않습니다. 두둥 아래처럼 this에 window객체가 찍힙니다.

이유는 globalCar(); 는 누가 불렀는지 멘션없이 밖에서 호출되었으므로 최상단 window 객체가 부른것입니다.
💡 핵심 -> this의 값은 함수를 호출한 방법에 의해 결정된다.

📍2. 메소드안에서 this

🚗 car 라는 객체에 name과 getName이라는 정보를 담아 줍니다.

 const car = {
      name: "KIA",
      getName: function () {
        console.log("car getName", this);
      },
    };

    car.getName();
}

car의 getName은 어떤 값을 print 할까요? 이곳에서 this는 car 그 자체를 가리키므로 예상대로 아래와 같이 name:"KIA" , getName 함수가 나옵니다.

그럼 car의 name만 결과값으로 받고 싶다면? 아래처럼 this.name을 적어주면 "KIA" 만 출력됩니다

 const car = {
      name: "KIA",
      getName: function () {
        console.log("car getName", this.name);
      },
    };

    car.getName();
}

📍3. 함수안에서 this

💡 함수안에서 this는 함수 주인에게 바인딩 됩니다.

function exFunction() {
  return this;
}
console.log(exFunction());

그럼 위 예시는 어떤 값을 print 할까요? 아래처럼 window가 나옵니다 왜냐?
함수의 주인이 window객체이기 때문입니다.

👉 하지만 엄격모드 "use strict" 에서는 함수 내의 this에 디폴트 바인딩이 없어서 undefined가 print됩니다.

"use strict";

function exFunction() {
  return this;
}
console.log(exFunction());



📍4. 이벤트 핸들러 안에서 this

👉 id가 btn이라는 값을 가진 버튼을 만들었습니다. 그리고 이 버튼을 누를 때 cargetName함수를 호출하겠습니다~

 <button id="btn">who are you</button>

이 상황에서 this는 어떤 값이 나올까요? car.getName이니까 car가 나올까요? 결과는

 const car = {
        name: "KIA",
        getName: function () {
          console.log("car getName", this);
        },
      };

      const button = document.getElementById("btn");
      button.addEventListener("click", car.getName);

아래와 같이 버튼을 누르면 버튼 태그 자체가 print됩니다.

왜? 이벤트리스너를 통해서 get.Name을 button이 호출했기 때문에 this는 button 태그 그 자체가 됩니다. 다시 한번 짚고 넘어갈게요
💡 핵심 -> this의 값은 함수를 호출한 방법에 의해 결정된다.


📍5. 화살표 함수로 쓴 this

화살표 함수에서의 this는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 함수가 속해있는 곳의 상위 this를 계승 받습니다. -> 이게 먼말이고 ? 즉, 화살표 함수에서의 this는 바깥 함수나 클래스의 this를 받아서 씁니다.

coolCar 안에 innderFunc 함수를 화살표 함수로 만들어 줌으로 써 속해있는 상위 범위의 this를 상속 받습니다. 상위에 있는 getName의 this를 상속 받는거죠~

     const coolCar = {
        name: "benz",
        getName: function () {
          console.log("getName", this);
          const innderFunc = () => {
            console.log("innerFunc", this);
          };
          innerFunc();
        },
      };
      coolCar.getName();

그래서 아래와 같이 둘다 동일한 값이 print되는걸 알 수 있습니다.



✅ This 값을 사용자의 의도대로 조작하기

👉 this 값을 사용자 의도대로 정해주기 위해선 명시적으로 짝을 지어주면 (바인딩 하면) 됩니다.
이 때 call, apply, bind를 사용할 수 있습니다.

📍call() 과 apply()

💡 여기서 call()과 apply() 메서드는 Function Object에 기본적으로 정의된 메서드입니다
💡 call() -> 인수 목록 , apply() -> 인수 배열을 받는다는 점이 중요한 차이점입니다.

call과 apply는 함수를 호출하는 함수입니다. 뭐 그냥 실행하는게 아니라~ 첫 번째 인자에 this로 세팅하고 싶은 객체를 넘겨주어 this를 바꾸고나서 실행합니다. 아래 예시를 살펴보겠습니다~

      const obj = {name: "Yona"};

      const greeting = function (city) {
        console.log(`Hi! my name is ${this.name}, I live in ${city}`);
      };

      greeting("seoul");
      greeting.call(obj, "seoul");
      greeting.apply(obj, ["seoul"]);

print된 값은 아래와 같습니다~

1) 처음 greeting("soeul")의 경우에 greeting이 실행 될 때 this에 아무런 세팅이 되어있지 않으므로 this는 window객체입니다~

2) 두 번째, 세번째 경우는 greeting.call(obj, "seoul");와 greeting.apply(obj, "seoul")은 this를 obj로 변경시켰으므로 원하는값이 나옵니다~

다시한번 짚고 넘어가자면

👉 call과 apply의 다른점은, 첫 번째 인자(this를 대체할 값)를 제외하고, 실제 greeting에 필요한 파라미터를 입력하는 방식입니다. call과는 다르게 apply함수는 두 번째 인자부터 모두 배열에 넣어야 한다는 점 ~

📍bind()

bind 함수가 call, apply와 다른점은 함수를 실행하지 않는다는 점입니다.
대신 bound함수를 리턴합니다. 이 bound함수(someoneGreeting)은 이제 this를 obj로 갖고 있기 때문에 나중에 사용해도 됩니다.

      const obj = {name: "Yona"};

      const greeting = function (city) {
        console.log(`Hi! my name is ${this.name}, I live in ${city}`);
      };

      const someoneGreeting = greeting.bind(obj);
      someoneGreeting("seoul");

print된 값은 아래와 같습니다~




📝 Reference

profile
산은 산, 물은 물, 코드는 코드

0개의 댓글