화살표 함수를 사용했을 때의 문제
const obj = {
name: "John",
greet: () => {
// 여기서 this는 obj가 아닌 외부 스코프(보통은 전역 객체)를 가리킴
console.log(`Hello, ${this.name}`);
}
};
obj.greet(); // "Hello, undefined"
// 왜냐하면 this.name은 전역 객체의 name을 찾기 때문일반 함수를 사용했을 때의 정상 동작
const obj = {
name: "John",
greet() {
// 여기서 this는 obj를 가리킴
console.log(`Hello, ${this.name}`);
}
};
obj.greet(); // "Hello, John"
// obj의 name 속성을 정상적으로 찾아서 사용실제 동작을 보여주는 더 자세한 예시
// 전역 스코프
const name = "Global Name";
// 객체 생성
const user = {
name: "John",
// 화살표 함수 사용
arrowGreet: () => {
console.log(`Arrow: Hello, ${this.name}`);
},
// 일반 함수 사용
normalGreet() {
console.log(`Normal: Hello, ${this.name}`);
}
};
user.arrowGreet(); // "Arrow: Hello, Global Name" (또는 브라우저에서 "Arrow: Hello, undefined")
user.normalGreet(); // "Normal: Hello, John"이런 차이가 발생하는 이유
-
일반 함수의 this
- 호출 시점에 this가 결정됨
- 객체의 메서드로 호출되면 this는 해당 객체를 가리킴
const user = { name: "John", greet() { console.log(this === user); // true console.log(this.name); // "John" } }; -
화살표 함수의 this
- 함수가 생성될 때 this가 결정됨
- 자신을 감싸는 스코프의 this를 그대로 사용
const user = { name: "John", greet: () => { console.log(this === window); // true (브라우저 환경에서) console.log(this.name); // undefined 또는 전역의 name 값 } };
올바른 사용 예시
객체 메서드
const user = {
name: "John",
// 이렇게 사용하세요
greet() {
console.log(`Hello, ${this.name}`);
},
// 또는 이렇게도 가능
greet: function() {
console.log(`Hello, ${this.name}`);
}
};중첩 함수에서는 화살표 함수가 유용
const user = {
name: "John",
friends: ["Mary", "Jane"],
printFriends() {
// 여기서는 일반 함수 사용
this.friends.forEach(friend => {
// 여기서는 화살표 함수가 유용
console.log(`${this.name}의 친구: ${friend}`);
});
}
};
user.printFriends();
// "John의 친구: Mary"
// "John의 친구: Jane"이러한 차이를 이해하면, 객체의 메서드를 정의할 때는 일반 함수를 사용하고, 콜백이나 중첩 함수에서는 화살표 함수를 사용하는 것이 좋다.