화살표 함수를 사용했을 때의 문제

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"

이런 차이가 발생하는 이유

  1. 일반 함수의 this

    • 호출 시점에 this가 결정됨
    • 객체의 메서드로 호출되면 this는 해당 객체를 가리킴
    const user = {
        name: "John",
        greet() {
            console.log(this === user); // true
            console.log(this.name); // "John"
        }
    };
  2. 화살표 함수의 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"

이러한 차이를 이해하면, 객체의 메서드를 정의할 때는 일반 함수를 사용하고, 콜백이나 중첩 함수에서는 화살표 함수를 사용하는 것이 좋다.

Vue.js에서 화살표 함수와 this 사용하기(option api)