This
- 일반적으로는 class에서 사용합니다.
- 보통 class로 생성한 인스턴스 객체를 this라고 합니다.
- 하지만 JavaScript에서는 그렇지 않고 this가 가리키는 대상이 항상 달라집니다.
1. 함수와 메서드
- 메서드는 객체의 프로퍼티로 함수가 정의되어야 합니다.
- 객체가 함수를 호출해야지 메서드입니다.
let user = {
name: 'kim',
underTwenty: function(age) {
return age < 20;
}
}
user.underTwenty(30); // 메서드
const under20 = user.underTwenty;
under20(15); // 객체 안에 정의된 함수라도, 이것은 메서드가 아닌 함수
- 위 예제는 함수와 메서드의 차이입니다.
2. this
- this는 실행 컨텍스트가 생성될 때 결정됩니다.
- 실행컨텍스트는 함수를 호출할 때 생성되기 때문에, this는 함수를 호출할 때 결정됩니다.
- this는 호출 방법에 따라서 대상이 달라지는 것입니다.
3. this의 동작 방식
3.1. 전역 공간에서 this
- 브라우저에서는 window
- Node.js에서는 global입니다.
var a = 1;
console.log(a);
console.log(window.a);
console.log(this.a);
//3개 모두 같음
3.2. 메서드로 호출될 때 this가 바라보는 대상 (암시적 binding)
-
객체의 프로퍼티에 할당된 함수를 호출하면, this는 해당 객체를 바라봅니다.
- 객체가 매서드로 호출되어야 합니다.
var name = 'lee'; var user = { name: 'kim', getName: function() { console.log(this.name); }, age: 50, child: { age: 15, underTwenty: function() { console.log(this.age); return this.age < 20 } } } user.getName(); // kim | getName 메서드는 user 객체를 바라봄 user.child.underTwenty(); // 15 | underTwenty 메서드는 child 객체를 바라봄 user.parentUnderTwenty = user.child.underTwenty; user.parentUnderTwenty(); // 50 | parentUnderTwenty 메서드는 user 객체를 바라봄
- 바로 이전을 보세요.
- getName의 this는 user
- underTwenty의 this는 child
3.3. 원하는 대상으로 this binding (명시적 binding)
-
call
- 함수 호출할 때, 원하는 객체를 인자로 넘겨줍니다.
user.child.underTwenty.call(user);
- this를 user로
- apply
- call하고 완전 같은데, 호출할 함수에 인자를 배열로 넘기느냐 아니냐 차이
-
bind
- call과 비슷하지만, 바로 호출하는 것이 아니라 대상을 묶어놓기만 하는 것(binding)
class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; **this.handleClick = this.handleClick.bind(this); //handle click의 this가 window가 되지 않도록 덮어 씌우는 것.** } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); } render() { return ( ); } }
arrow function
- this의 대상이 어떤 객체가 호출했느냐로 결정되지 않습니다.
- 함수 내부에 this는 없으며, scope chain의 가장 가까운 this로 대상을 결정합니다.
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
**** }
handleClick = () => {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
- handleClick의 this가 Toggle이 되었습니다.
Comments