this, binding

Kingmo·2022년 4월 10일
0

1. this

자바스크립트의 this함수는 다른 언어의 this키워드와는 약간 다르게 작동한다.
또한 strict modenon-strict mode에도 약간의 차이가 있다.

대부분의 경우 this의 값은 함수의 호출 방식에 따라 결정된다.
때문에 실행중에 this를 할당할 수 없고 함수를 호출할 때 마다 다를 수 있다.

this와 같이 누가 실행을 시켰느냐 에 따라 달라지는 것을 동적 스코프라고 한다.


2. bind

그래서 이 호출할 때마다 다를 수 있는 this의 특성을 제어하고자
ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입했고,
ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.


3. 동적스코프, bind 확인하기

처음 콘솔에 this를 입력하면 윈도우가 나온다.
객체aaaqqq를 할당하고 qqq에서 this를 확인하면

qqq안에서의 thisaaa를 가리키는 것을 볼 수 있다.

여기서 qqq에 할당한 함수를 화살표 함수로 바꾸면 어떻게 될까?

화살표 함수로 바꾸면 동적 스코프가 일어나지않고 객체 qqq안의 this는
처음 콘솔에 this를 입력했을 때와 같이 윈도우를 가리키는 것을 볼 수 있다.

이 처럼 바뀌지 않는 thislexical this라고 한다.


4. Class Component에서의 this, binding 사용

다음과 같이 클래스형 컴포넌트로 버튼을 클릭할 때마다
count를 1씩 올리고 리렌더링하는 기능을 구현하면 작동하지 않는다.

import { Component } from 'react'

export default class CounterPage extends Component {
  state = {
    count: 99,
  }

  onClickCounter () {
  	this.setState((prev) => ({
    	count: prev.count + 1
    })
  }
  
  render() {
  	return (
      <div>
        <div>현재카운트: {this.state.count}</div>
        <button onClick={this.onClickCounter}>카운트 올리기!!!</button>
      </div>
    )
  }
}

위 코드는 reder()를 기준으로 위의 this와, 안의 this는 동적스코프라는 특성 때문에
다른 값을 가지게되어 작동하지 않는다.

그래서 이 때 onClickCounter함수를 화살표 함수로 바꾸면
lexical this를 사용하여 의도한 대로 작동시킬 수 있다.

import { Component } from 'react'

export default class CounterPage extends Component {
  state = {
    count: 99,
  }

  onClickCounter = () => {
  	this.setState((prev) => ({
    	count: prev.count + 1
    })
  }
  
  render() {
  	...
  }
}

혹은 render()문 안의 this를 다음과 같이 bind 처리하면
render()안의 this로 함수의 this를 바인딩 한다.

import { Component } from 'react'

export default class CounterPage extends Component {
  state = {
    count: 99,
  }

  onClickCounter () {
  	this.setState((prev) => ({
    	count: prev.count + 1
    })
  }
  
  render() {
  	return (
      <div>
        <div>현재카운트: {this.state.count}</div>
        <button onClick={this.onClickCounter.bind(this)}>카운트 올리기!!!</button>
      </div>
    )
  }
}
profile
Developer

0개의 댓글