자바스크립트에서 this는 인스턴스(객체) 자신을 가리키는 참조변수이다. 즉 this가 객체 자신에 대한 참조 값을 가지고 있다는 뜻이다. 이러한 this는 함수가 호출될 때 결정이 되며, 이렇게 함수가 호출될 때마다 this가 동적으로 결정되는 것을 this가 그 객체에 바인딩된다고 한다.
프로퍼티: 어떠한 값이 다른 값과 연관되어 있을 때의 값을 property라고 하며, 점표기법(.length)와 같은 방식으로 호출
이러한 this는 누가 호출했느냐에 따라 값이 바뀐다는 특징을 가지고 있다. 아래의 코드는 그 예시인데, car라는 객체에서 정의된 getName을 어디서 호출했느냐에 따라 this가 달라지는 예시이다. globalCar처럼 전역에서 호출 주체 없이 호출이 될 경우 this는 전역 객체인 window를 가리키게 되고, car2에 의해 호출이 될 경우 this는 car2 객체를 가리키게 된다.
const car = {
name: 'KIA',
getName: function() {
console.log('car getName', this)
}
}
car.getName() // car라는 객체에 대한 출력이 나옴
const globalCar = car.getName
globalCar() // window라는 전역 객체에 대한 출력이 나옴
const car2 = {
name: 'hyundai',
getName: car.getName,
}
car2.getName() // car2라는 객체에 대한 출력이 나옴
따라서 위와 같은 문제를 해결하기 위해서는 this를 고정시켜줘야 하는데 이 키워드가 bind이며, 예시 코드는 아래와 같으며 아래와 같이 .bind()로 객체를 지정해 줄 경우 호출 위치, 주체와 상관없이 지정된 객체를 호출하게 된다.
const bindGetName = car2.getName.bind(car)
bindgetName() // car라는 객체가 출력됨
화살표 함수에서는 this를 바인딩 하지 않으며, this는 함수가 속해 있는 상위 스코프의 this를 가리킨다. 따라서 아래의 코드처럼 innerFunc의 함수 형태를 화살표 함수로 변경할 경우 innerFunc()를 호출할 때 상위 스코프인 testCar를 가리키게 된다.
const testCar = {
name: 'benz',
getName: function () {
console.log('getName', this) // testCar를 가리킴
const innerFunc = function() {
console.log('innerFunction', this)
}
innerFunc() // window 객체를 가리킴
}
}
const testCar = {
name: 'benz',
getName: function () {
console.log('getName', this) // testCar를 가리킴
const innerFunc = () => {
console.log('innerFunction', this)
}
innerFunc() // 상위 스코프인 testCar를 가리킴
}
}
만약 이러한 this를 사용하고 싶으면 일반함수를 사용하는 것이 좋은데 이유는 .bind()를 통해서 객체를 지정해 줄 수 있기 때문에 예측 가능성이 높아지기 때문이다. 반대로 어떠한 객체의 내부에서 함수를 사용할 경우 상위 스코프를 가져오는 경우가 많기 때문에 화살표 함수를 사용하는 편이 좋다.
Reference
https://velog.io/@arski/JavaScript-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-this%EB%9E%80
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
https://poiemaweb.com/js-this
https://youtu.be/tDZROpAdJ9w?si=Gah0lp83hsuYXK8L
'JavaScript' 카테고리의 다른 글
일반함수 VS 화살표 함수 (0) | 2023.12.22 |
---|