자바스크립트의 this
함수는 다른 언어의 this
키워드와는 약간 다르게 작동한다.
또한 strict mode
와 non-strict mode
에도 약간의 차이가 있다.
대부분의 경우 this
의 값은 함수의 호출 방식에 따라 결정된다.
때문에 실행중에 this
를 할당할 수 없고 함수를 호출할 때 마다 다를 수 있다.
this
와 같이 누가 실행을 시켰느냐 에 따라 달라지는 것을 동적 스코프
라고 한다.
그래서 이 호출할 때마다 다를 수 있는 this
의 특성을 제어하고자
ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입했고,
ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.
처음 콘솔에 this
를 입력하면 윈도우가 나온다.
객체aaa
에 qqq
를 할당하고 qqq
에서 this
를 확인하면
qqq
안에서의 this
는 aaa
를 가리키는 것을 볼 수 있다.
여기서 qqq에 할당한 함수를 화살표 함수로 바꾸면 어떻게 될까?
화살표 함수로 바꾸면 동적 스코프가 일어나지않고 객체 qqq
안의 this는
처음 콘솔에 this
를 입력했을 때와 같이 윈도우를 가리키는 것을 볼 수 있다.
이 처럼 바뀌지 않는 this
를 lexical this
라고 한다.
다음과 같이 클래스형 컴포넌트로 버튼을 클릭할 때마다
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>
)
}
}