자바스크립트의 this는 일반적인 언어의 this와 다르다. 보통 메서드가 정의된 객체를 참조할 것이라고 생각할 것이다. 이런 개념을 "bound this"라고 한다. 반면 자바스크립트에서는 대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정된다. (출처: MDN)
undefinedWindow, node에서는 nodelet group = {
title: "1모둠",
students: ["보라", "호진", "지민"],
showList() {
this.students.forEach(function () {
alert(this); ---> 일반 함수 호출: this ➡️ Window
})
2) this.students.forEach(student => alert(this.title + ': ' + student)); ---> 화살표 함수 호출: this ➡️ showList()의 this ➡️ group
}
}
group.showList();
const user = {
name: "John",
whoAmI: () => { console.log(this) } ---> 화살표 함수 호출: this ➡️ user의 this ➡️ Window
}
user.whoAmI();
const user = {
name: "John",
whoAmI: () => { console.log(this) }
}
const otherUser = user.whoAmI;
otherUser(); ---> 일반 함수 호출: this ➡️ Window
🙉 otherUser(); ➡️ Window / strict모드에서는 undefined

➡️ this가 가리키는 게 다른 문제를 해결하기 위해 ES6에서 화살표 함수가 나왔다.
.) 앞에 있는 애const user = {
name: "John",
whoAmI: function() {
console.log(this);
}
}
user.whoAmI();
🙉 user.whoAmI(); ➡️ Object

whoAmI() 앞에 적혀있는 오브젝트.를 보면 된다. user이다. 이렇게 호출한 방식은 함수가 아닌 메서드로 호출한 것이다. 메서드는 객체의 property에 할당된 함수이다.
document.querySelector("#button").addEventListener("click", user.whoAmI);
🙉 click ➡️ button

user.whoAmI를 넘겼을 뿐, 호출은 button이 했다.
bind(this가 될 대상)const binded = otherUser.bind(user); // user를 this로 받겠다.
document.querySelector("#button").addEventListener("click", binded);
🙉 click ➡️ user

call(this가 될 대상, ...property), apply(this가 될 대상, [properties])otherUser.call(user);
otherUser.apply(user);
🙉 otherUser() ➡️ user

출처: 라이언의 머릿속
문제! 여기서 alert가 실행될까요? 🤔
function programmer() {
this.isSmart = false;
this.upgrade = function (version) {
this.isSmart = !!version;
work();
}
function work() {
if (this.isSmart) {
window.alert('I can do my work! I am smart!');
}
}
}
var programmer = new programmer();
programmer.upgrade(1.1);
실행되지 않는다 🫢 this.upgrade 안에서는 isSmart = true이지만, work()를 일반 함수 호출했기 때문에 work() 안에서 this는 window가 된다. window에는 isSmart가 없기 때문에 this.isSmart는 undefind가 된다.
function programmer() {
this.isSmart = false;
this.upgrade = function (version) {
this.isSmart = !!version;
this.work();
}
this.work = function () {
if (this.isSmart) {
window.alert('I can do my work! I am smart!');
}
}
}
var programmer = new programmer();
programmer.upgrade(1.1);

참고 자료