자바스크립트 bind 메소드 – this의 이해

자바스크립트 bind 메소드 는 this 키워드에 대해 명시적으로 바인딩 할 때 사용하는 메소드이다.

자바스크립트의 this는 다른 타 Language와는 달리 동작하게 되는데, 그래서 명시적 바인딩을 할 때 사용하는 메소드 중 하나가 bind() 이다.

bind 메소드는 call, apply와 더불어 대표적인 명시적 바인딩 메소드이며, function의 프로토타입(Prototype)으로 모든 함수에서 접근해서 사용할 수 있다.

암시적바인딩이란 – 자바스크립트 this 의 성격

객체의 프로퍼티로 접근해서 실행하는 것을 암시적 바인딩이라고 한다.

아래의 예시를 보면, 영희 객체의 whoAmI 함수에서는 this가 사용되고 있다. 그리고 철수의 객체에 whoAmI를 넣어주고 있다.

<script>
      const 영희 = {
        name: "영희",
        whoAmI: function () {
          console.log(this.name);
        },
      };
      const 철수 = { name: "철수" };
 
      철수.whoAmI = 영희.whoAmI;
      영희.whoAmI(); 
      철수.whoAmI(); 
</script>

객체의 프로퍼티로 접근해서 실행하는 것을 암시적 바인딩

이것의 결과는 결국 this를 “누가 호출했냐”에 달려있다. 영희.whoAmI()는 영희 객체의 this가 참조되며, 철수.whoAmI()는 철수 객체의 this가 참조됩니다.

즉, 해당 함수의 호출을 누가 했냐에 따라 함수 내에 사용된 this가 결정이 된다. 누가 함수를 꺼내었는가?

<script>
      const whatThisIs = {
        name: "It's me",
        whatIs: function () {
          console.log(this);
        },
      };
      whatThisIs.whatIs();
      const fnWhatIs = whatThisIs.whatIs;
      fnWhatIs();
    </script>

위의 코드에서 whatThisIs.whatIs();와 fnWhatIs();는 분명 똑같은 함수를 호출했지만 this의 값이 다르게 나온다.

왜냐하면 “호출한” 주체가 다르게 때문에 “나 자신(this)”도 달라지게 된다.

<script>
      const person = {
        age: 30,
        whoAmI: function () {
          console.log(this);
        },
      };
 
      person.whoAmI();//person객체가 호출
 
      const myFunc = person.whoAmI;
 
      myFunc(); //최상위 객체에서 호출
</script>
 

person 객체가 호출한 함수에서는 this를 person 객체로 참조하게 되나, const myFunc로 받아서 호출하면 this는 window 객체를 참조하게 된다.

두번째 this는 윈도우 객체를 참조

setTimeout 의 경우, 기본으로 this 키워드는 window(또는 global) 객체로 지정된다.

아래 예제에서, setTimeout에 분명 obj,callme를 넘겼지만, 이건 넘겼을 뿐이고 호출한 것이 아니므로 실제 setTimeout에서 호출될 때에는 this.name은 가장 상위에서 찾게 된다.

<script>
      function myNameIs() {
        console.log(this.name);
      }
 
      var obj = {
        name: "철수",
        callme: myNameIs,
      };
 
      setTimeout(obj.callme, 1000);
      name = "this is this" // ★ setTimeout의 callme 내의 this
    </script>

위의 예제 역시 1초 후에 실행되는 setTimeout내에서의 this는 이미 실행된 name을 참조하게 된다.

자바스크립트 bind - 호출한 주체가 다르게 때문에 this도 달라지게 된다

따라서 명시적으로 특정 객체를 지정해야 하는 경우 bind()메소드를 사용할 수 있다.

자바스크립트 bind 메소드의 사용 – this 고정

위의 예제를 다시 bind() 함수로 구성하면 다음과 같이 this의 항목을 명시해서 넘길 수 있다.

즉, 호출을 누가하느냐에 따라 this의 참조가 바뀔 수 있기 때문에 이를 고정(bind())하는 것이다.

<script>
      function myNameIs() {
        console.log(this.name);
      }
 
      var obj = {
        name: "철수",
        callme: myNameIs,
      };
      setTimeout(obj.callme.bind( obj ), 1000); //★ .bind(obj) 추가
      name = "this is this"
    </script>

위의 예제는 bind 매개변수에 this 참조값을 obj로 지정하였고 결과는 1초 후 “철수”가 출력되게 된다.

이상으로 자바스크립트 bind 메소드에 대해서 알아보았고, 좀 더 상세한 케이스는 MDN prototype.bind() 문서를 참조할 수 있다.

비슷하게 헷갈릴 수 있는 자바스크립트 함수 스코프에 대한 클로저 함수 에 대한 내용도 함께 확인하면 도움이 될 것으로 보인다.