[JavaScript] this, call, apply, bind

ttining·2025년 4월 21일

JavaScript에서 this 키워드는 함수 호출 방식에 따라 동적으로 결정되며,
call, apply, bind는 이 this 값을 명시적으로 설정하는 데 사용된다.


📍 this란 무엇인가?

this는 함수가 호출될 때 해당 함수가 속한 객체를 참조하는 키워드이다.
호출 방식에 따라 this가 달라지며, 다음과 같은 패턴으로 나뉜다.

1️⃣ 일반 함수 호출

function show() {
  console.log(this);
}

show(); // 브라우저: window, Node.js: global
  • 전역 컨텍스트에서는 thiswindow (또는 Node.js에서는 global)를 가리킨다.

2️⃣ 객체의 메서드 호출

const obj = {
  name: 'JS',
  say() {
    console.log(this.name);
  },
};

obj.say(); // 'JS'
  • thisobj를 가리킨다.

3️⃣ 클래스에서의 this

class User {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hi, I'm ${this.name}`);
  }
}
const user = new User('Alice');
user.greet(); // Hi, I'm Alice
  • 클래스의 메서드에서는 해당 인스턴스를 가리킨다.

4️⃣ 이벤트 핸들러에서의 this

const button = document.querySelector('button');
button.addEventListener('click', function () {
  console.log(this); // 클릭된 button 요소
});
  • 전통적인 함수에서는 this가 이벤트 대상(Element)을 가리킨다.
  • ⚠️주의 : 화살표 함수 사용 시 상위 스코프의 this를 캡처한다.



📍 call, apply, bind

이들 메서드는 모두 함수를 호출하거나 새로운 함수를 반환하면서 this를 지정할 수 있게 해준다.


1️⃣ call

함수를 호출하면서 this를 명시적으로 지정한다.

function greet() {
  console.log(`Hello, I'm ${this.name}`);
}

const person = { name: 'Alice' };

greet.call(person); // Hello, I'm Alice

추가 인자가 있다면 ,로 나열하면 된다.

function introduce(age) {
  console.log(`${this.name} is ${age} years old`);
}

introduce.call(person, 25); // Alice is 25 years old

2️⃣ apply

call과 유사하지만, 인자를 배열로 받는다.

introduce.apply(person, [30]); // Alice is 30 years old
  • applycall과 동일하게 this를 지정하지만, 인자를 배열 형태로 전달한다.
  • 이는 인자 개수가 동적으로 결정되는 상황에서 유용하다.

3️⃣ bind

call, apply와 달리 함수를 즉시 실행하지 않고, this가 바인딩된 새로운 함수를 반환한다.

const boundFunc = greet.bind(person);

boundFunc(); // Hello, I'm Alice

인자도 사전에 고정 가능하다.

const boundIntroduce = introduce.bind(person, 40);

boundIntroduce(); // Alice is 40 years old



⚠️ 주의할 점

1️⃣ 화살표 함수의 this

화살표 함수는 자신의 this를 가지지 않고, 외부 스코프의 this를 캡처한다.

const obj = {
  name: 'Bob',
  greet: () => {
    console.log(this.name);
  }
};

obj.greet(); // undefined (전역 객체의 name)

2️⃣ 메서드를 분리하면 this가 사라짐

const person = {
  name: 'Tom',
  greet() {
    console.log(this.name);
  },
};

const fn = person.greet;
fn(); // undefined

const fnArrow = () => person.greet();
fnArrow(); // Tom

→ 해결: bind로 고정하거나 call, apply로 호출.




✅ 언제 어떻게 사용할까?

상황추천 메서드
함수 실행 시 this 지정call / apply
함수 실행을 나중에 하고 싶을 때bind
인자 배열로 전달 필요apply
this 유지가 필요한 이벤트 등bind

이처럼 상황에 따라 적절한 메서드를 선택하면 this와 관련된 오류를 줄이고, 더욱 명확한 코드를 작성할 수 있다.

profile
내가 보려고 만든 벨로그 *'-'*

0개의 댓글