Post Detail Page
tech
Javascript에서 this 바인딩 이해하기
함수 호출 방식에 따라 결정되는 this
자바스크립트의 this
는 함수가 어떻게 호출되었는가에 따라 가리키는 값이 달라집니다.
📌 일반 함수 호출
const cafe = {
brand: '이디야',
menu: '아메리카노',
print: function () {
console.log(this);
},
};
const myCafe = cafe.print;
myCafe(); // 일반 함수 호출
- myCafe 변수에
cafe.print
를 할당하고 호출했기 때문에myCafe()
는 전역 컨텍스트에서 실행됩니다. 이때this
는 전역 객체인window
를 가리킵니다.
📌 메서드 호출(객체 프로퍼티 함수)
함수가 어떤 객체의 메서드로서 호출되는지에 따라 this가 달라집니다.
const cafe = {
brand: '이디야',
menu: '아메리카노',
print: function () {
console.log(this);
},
};
cafe.print();
{brand: '이디야', menu: '아메리카노', print: ƒ}
this
는 자신이 포함된 객체인 cafe를 가리키고, console.log(this)는 cafe 객체를 출력하게 됩니다.
const cafe = {
brand: '이디야',
menu: '아메리카노',
newCafe: {
brand: '이디야',
menu: '라떼',
print: function () {
console.log(this);
},
},
};
cafe.newCafe.print();
{brand: '이디야', menu: '라떼', print: ƒ}
this
는 호출된 메서드의 주체인 newCafe 객체 자체를 가리키고, console.log(this)는 newCafe 객체를 출력하게 됩니다.
📌 생성자 함수 호출
function Cafe(menu) {
console.log(this);
this.menu = menu;
}
let myCafe = new Cafe('latte');
console.log(myCafe);
Cafe {menu: 'latte'}
new
키워드를 사용하면, 자바스크립트는 새로운 객체를 생성하고 그 객체를this
로 바인딩합니다.
🔎 new 키워드를 삭제하고, Cafe 함수를 일반 함수로 사용한다면?
function Cafe(menu) {
console.log(this);
this.menu = menu;
}
let myCafe = Cafe('latte'); // 일반 함수로 사용됨
console.log(myCafe);
new
키워드를 생략하면 일반 함수로 호출되며,this
는 전역 객체window
를 가리킵니다.
console.log(window.menu); // 'latte'
📌 콜백 함수
const cafe = {
brand: '이디야',
menu: '',
setMenu: function (menu) {
this.menu = menu;
},
};
function getMenu(menu, callback) {
callback(menu);
}
getMenu('핫초코', cafe.setMenu);
console.log(cafe);
- getMenu 함수에서
cafe.setMenu
를 콜백으로 전달하면, setMenu는 메서드로서 호출되지 않고, 일반 함수로 호출됩니다.
console.log(window.menu) // 핫초코
🔎 메서드로 직접 호출하기
const cafe = {
brand: '이디야',
menu: '',
setMenu: function (menu) {
this.menu = menu;
},
};
function getMenu(menu) {
cafe.setMenu(menu); // 메서드 호출
}
getMenu('핫초코');
console.log(cafe);
{brand: '이디야', menu: '핫초코', setMenu: ƒ}
- cafe.setMenu 메서드로 호출되므로
this
는 cafe 객체를 가리키게 됩니다. 이때 this.menu는 cafe 객체의 menu에 '핫초코'를 할당하게 됩니다.
📌 화살표 함수
💡 화살표 함수의 this
화살표 함수의 this는 호출 방식과 상관없이 함수가 선언된 위치의 상위 스코프를 참조합니다.
이는 일반 함수가 호출될 때마다 this가 동적으로 바인딩되는 것과 달리, 화살표 함수는선언 시점
의 this가 고정됩니다.
🚨 일반 함수(콜백 호출)에서의 this 문제
function Counter() {
this.count = 0;
setInterval(function () {
this.count++;
console.log(this.count);
}, 2000);
}
const counter = new Counter();
setInterval
의 콜백 함수는 일반 함수로서 실행됩니다. 일반 함수의 경우this
는 함수가 호출된 방식에 따라 결정되며, 이때 콜백 함수는 전역 컨텍스트에서 실행되기 때문에,this
는 전역 객체인window
를 가리키게 됩니다.this.count++
를 하려고 하면,this
는 Counter 객체가 아닌window
를 가리키기 때문에NaN
이 2초마다 찍히게 됩니다.
화살표 함수에서의 this 바인딩
function Counter() {
this.count = 0;
setInterval(() => {
this.count++;
console.log(this.count);
}, 2000);
}
const counter = new Counter();
화살표 함수
는 자신이 선언된 위치의 상위 스코프를 참조합니다. 화살표 함수가 Counter 객체의 컨텍스트에서 선언되었기 때문에,this
는Counter 객체
를 가리킵니다.
화살표 함수와 메서드 호출
const cafe = {
brand: '이디야',
menu: '아메리카노',
print: () => {
console.log(this);
},
};
cafe.print();
- print 메서드는 cafe 객체의 속성으로 정의되었지만, 화살표 함수는 cafe 객체의 상위 스코프, 즉 전역 객체
window
를 참조하게 됩니다. - 객체의 메서드로서
this
를 올바르게 바인딩하기 위해서는 일반 함수를 사용하는 것이 좋습니다.