JavaScript

클래스에서 바인딩 현상이 발생하였을 때

Gushers 2022. 12. 28. 22:03

자바스크립트를 공부하다보면 클래스를 사용해본 경험이 있었을 것이다.

나 또한 리액트를 계속 공부하면서 우아한 테크 코스에서 오랜만에 클래스를 사용해봤고, 최근에 ES5 생성자 함수를 공부하면서 내가 지금까지 잘못알고있었던 지식이 있었다.

물론 자바스크립트를 잘하는 사람이라면 이 글을 보고 당연하다고 생각하겠지만, 나처럼 모르는 사람이 있을 수도 있기 때문에 한번 작성해보고자 한다.

바인딩

누구나 한번쯤은 클래스에서 바인딩 현상을 경험하였을 것이다.

나또한 처음에 자바스크립트를 배우면서 바인딩 현상을 경험했고, 최근에 우테코에서도 바인딩 현상이 일어나 이를 해결했던 경험이 있었다.

그래서 바인딩 현상을 해결하고자 알려진 대표적인 방법은 아래와 같다.

바인딩 현상 해결방법

  1. bind() 함수 사용

ES5 생성자 함수에서 바인딩 현상이 발생하였을 때 해결하기 위한 방법으로 ES5뿐만 아니라 ES6에서도 사용이 가능하다.

bind 메서드의 첫번째 인자로 내가 설정하고 싶은 this의 값을 같이 넘겨주면 된다.

하지만 이 함수의 최대 단점은 너무 위험한 메서드이다.

왜냐하면 bind 메서드는 강제로 this의 값을 설정해주기 때문에 this의 값을 확실하게 알지 못한상태에서 이 메서드를 사용하게 되면 잘못된 this값이 설정되게 된다.

그렇기 때문에 this의 값을 정확히 알아야지 이 메서드를 안전하게 사용하는 것이 가능하다.

  1. Arrow 함수

ES6에서 새로 나온 화살표 함수를 이용하면 bind 현상을 해결할 수 있게된다.

그 이유는 일반적인 함수에서의 this는 몇가지 경우에 따라 값이 동적으로 변하게 된다.
(이 경우에 대해서는 ES5글에 적어놓았다.)

하지만 화살표 함수는 항상 상위 스코프를 가르키기 때문에 bind현상을 해결해준다.

Class에서 사용할 때

class User = {
 constructor(user){
   this.user = user;
   this.check(this.print);
 }

  print(){
    console.log(this.user);
    // 코드
  }

  check(callback){
    // 코드
  }
}

만약에 이런 코드가 있을 때 인자로 전달되는 print() 메서드의 경우 this 값을 잃어버리게 된다.
그렇기 때문에 두번째 방법을 이용해서 바인딩 현상을 해결하는 것이 좋은데 여기서 새로운걸 배우게 되었다.

나는 그동안 바인딩 현상이 일어나면 해당 메서드를 화살표 함수로 변경해주었다.

class User = {
 constructor(user){
   this.user = user;
   this.check(this.print);
 }

  print =()=> {
    console.log(this.user);
    // 코드
  }

  check(callback){
    // 코드
  }
}

문제점

이렇게 메서드 자체를 화살표 함수로 바꿔주게 되면 제대로 작동은 하지만 한가지 문제점이 발생했다.
해당 클래스를 콘솔에 찍은 뒤 prototype을 보게 되면 print 메서드가 사라진 것을 볼수있다.
이처럼 화살표 함수로 선언을 하면 클래스 내부에서는 동작이 가능하기는 하지만 더 이상 메서드가 아니기 때문에 이렇게 하는 것은 좋은 방법이 아니였다.

앞으로는 이렇게!!

솔직히 메서드를 화살표 함수로 변경하게 되면 미관상 좋지도 않다. 앞으로는 바인딩 현상이 일어났을 때는 메서드를 화살표 함수로 바꾸지 않고, 호출할 때 화살표 함수로 호출하는 것이 옳바른 방법이라고 공부하였다.

class User = {
 constructor(user){
   this.user = user;
   this.check(()=>this.print);
 }

  print() {
    console.log(this.user);
    // 코드
  }

  check(callback){
    // 코드
  }
}

이렇게 호출할때 한번 감싸서 고차함수의 형태로 메서드를 호출하게 되면 깔끔하게 바인딩 현상도 사라지게 되고, prototype에서 메서드가 사라지는 현상도 없어지게 된다.