⌨
This
March 26, 2022
일반적으로 this는 클래스(class)에서만 사용하며, class로 생성한 인스턴스 객체를 의미하나, JavaScript에서는 그렇지 않고 this가 가르키는 대상이 항상 달라집니다.
함수와 메서드
- 함수와 메서드는 모두 function 키워드로 함수를 정의한 것을 의미
- 메서드는 객체의 프로퍼티로 함수가 정의되어야 한다. 중요한건 객체가 함수를 호출해야 메서드이다!!!
let user = {
name: 'kim',
underTwenty: function (age) {
return age < 20;
},
};
user.underTwenty(30); // 메서드
const under20 = user.underTwenty;
under20(15); // 객체 안에 정의된 함수라도, 이것은 메서드가 아닌 함수이다
this
- this란? this가 바라보고 있는 객체인데, 상황에 따라 대상이 달라진다.
- this는 실행컨텍스트가 생성될 때 결정된다. 실행컨텍스트는 함수를 호출할 때 생성되므로, this는 함수를 호출할 때 결정된다.
this의 동작 방식
전역 공간에서 this
- client(브라우저)에서는 window
- Node.js에서는 global
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
메서드로 호출될 때 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 객체를 바라봄
arrow function에서 this
- 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>
);
}
}
원하는 대상 this binding (명시적 binding)
call
-
함수를 호출할 때, 원하는 대상의 객체를 인자로 넘겨준다.
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.child.underTwenty.call(user); // 50
apply
- call 메서드와 완전히 같은 기능이나, 호출할 함수에 인자를 배열로 넘기느냐 or not
bind
- call과 비슷하지만, 바로 호출하는 것이 아니라 대상을 묶어놓기(binding)만 하는 것
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
**this.handleClick = this.handleClick.bind(this);**
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button **onClick={this.handleClick}**>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
- event listener는 내부적으로 this를 이벤트가 일어난 엘리먼트로 대상을 잡아놓기 때문에 handleClick 내부의 this가 Class를 가르키는 것이 아닌, 엘리먼트를 가르키게 됨
this 예제
var name = 'lee';
var user = {
name: 'kim',
getName: function () {
console.log(this.name); // kim
var inner = function () {
console.log(this.name); // lee
};
inner();
},
};
user.getName();
this 예제 더 풀어보기: 7 Interview Questions on “this” keyword in JavaScript.