JS를 어느정도 공부하고, 리액트를 공부하는 과정에서
많은 어려움을 느껴 다시 JS를 복습해보자!
오늘은 Class 문법을 복습하기 전에 this에 대해서 알아보자.!!😀
this
는 함수를 호출한 객체를 의미하지만, 좀 더 간단하게 말하면 호출한 놈 이라고 많이들 표현한다.
지금부터 this
가 어디에 바인딩 되는지 알아보자.
( *바인딩 : 묶는 것 이라는 뜻으로 함수를 호출한 객체와 this
를 연결시키는 것을 말한다.)
예제1
// 객체 내부에서 함수를 작성하고 호출
const user1 = {
name: 'hisu',
age: 25,
onThisHandler: function(){
console.log(this.name) // hisu
console.log(this.age) // 25
}
}
user1.onThisHandler()
-----------------------------------
// 함수를 따로 만들고 객체에서 호출
const thisHandler = function(){
console.log(this.name)
console.log(this.age)
console.log(this === user)
console.log(this === window)
}
const user2 = {
name: 'hisu',
age: 25,
onThisHandler: thisHandler
// user객체의 데이터를 반환하고,
// this === user는 true를 반환한다.
// this === window는 false를 반환한다.
}
user2.onThisHandler()
-----------------------------------
const printThis = user1.onThisHandler
printThis() // window 객체를 반환하고,
// this === user는 false를 반환한다.
// this === window는 true를 반환한다.
위에 코드 처럼
this
는 함수를 호출한user
객체를 바라보고 있다.
즉,this
는 호출되는 순간의 해당 객체를 의미한다고 보면 된다.
하지만, 코드의 아랫줄을 보면 함수를 호출한 것은 printThis라는 변수가 되기 때문에
이는 곧this
가 전역 객체를 참조한다.. 전역 객체는 브라우저에서는 window 객체를, Node.js에서는 global 객체를 의미한다..
예제2
const hisu = {
name: 'hisu',
age: 25,
onThisHandler: function(){
console.log(this)
}
}
user.onThisHandler() // hisu 객체를 반환한다.
const alice = {
name: 'alice',
age: 23,
onThisHandler: user.onThisHandler
//
}
user2.onThisHandler() // alice 객체를 반환한다.
위에 코드처럼 함수는 hisu 라는 객체에 있었지만,
호출은 alice 객체에서 호출되었기 때문에this
는 alice 객체를 바라본다.
이렇게this
는 호출된 그 객체를 바라본 다는 것을 알 수 있다.
예제
// <button></button>
let btn = document.querySelector(button);
btn.addEventListener('click', function(){
console.log(this) // btn 객체를 반환한다.
console.log(this === btn) // true를 반환
})
위의 코드와 같이
this
가 담긴 함수를 호출한 것은btn
이기 때문에,
this
는btn
객체를 바라본다.
해당 메서드는 window
객체를 바라보고 있는 객체가 아닌 연결 짓고 싶은 객체와 묶어주는 메서드이다.
또한, 이 메서드는 한번만 사용이 가능하다.
이해를 돕기위해 아래 코드를 확인하자.
예제
function printUser(){
console.log(this)
}
let person1 = {
name: 'hisu'
}
let person2 = {
name: 'alice'
}
let printUser1 = printUser // window 객체를 반환
let printUser2 = printUser.bind(person1) // person1 객체를 반환
let printUser3 = printUser.bind(person2)// error
// 이미 bind 되어있는 함수는 다시 bind 할 수 없다.
화살표 함수에서 this
는 기본 함수와 다르게 더 큰 범위의 객체를 참조한다.
이게 무슨 말이냐면, function함수에서는 부모객체를 참조했다고 하면,
화살표 함수는 조부모의 객체를 참조한다고 보면 된다.
// BAD
const hisu = {
name: 'hisu',
age: 25,
onThisHandler: function(){
setTimeout(function(){
console.log(this.name)
},1000) // 해당 함수는 undefined를 반환함.
// 이유는 일반 함수이기 때문에 this의 범위가 맞지 않음.
}// 만약 일반함수로 undefined가 나오지 않게 하려면, .bind(this)를 이용!
}
//GOOD
const hisu = {
name: 'hisu',
age: 25,
onThisHandler: function(){
setTimeout(()=>{
console.log(this.name)
},1000) // 'hisu'를 출력!
}
}
위의 코드처럼, 화살표 함수를 사용할 때는
this
가 어떻게 동작하는지 항상 주의해야 한다.
일반 함수에서와 달리,this
가 상위 스코프에서 상속되므로this
가 변경되는 경우가 많지 않다.
또한, 화살표 함수에서this
를 명시적으로 바인딩할 수 없다.call
,apply
,bind
메서드를 사용하여this
를 변경하는 것도 불가능하다.
따라서, 화살표 함수가 this를 가리키지 않는 예기치 않은 결과를 방지하기 위해, this를 명시적으로 바인딩해야 하는 경우에는 일반 함수를 사용하는 것이 좋다.
this에 대해서 잘 모른 상태로 class를 보았을 땐 잘 이해를 못했지만,
왜 class를 공부하기 전에 this에 대해서 명확하게 알고 넘어가야하는지 이해가 된다.
블로그에 올라온 글로만 이해하려고 했을 때 어려웠지만, 유튜브 강의를 보며 직접 코드를 치며 이해하니 좀 더 쉽게 이해할 수 있었다.
😀꿀팁 출처
유튜브 강의