본문 바로가기
Web Frontend

JavaScript this 이제 헷갈리지말자

by 코라채 2025. 1. 5.
728x90

자바스크립트에서 this는 많은 개발자들에게 혼란을 주는 개념입니다. this가 참조하는 값은 코드가 실행되는 문맥(context) 에 따라 달라지기 때문인데요. 특히 함수나 메서드 내에서 this가 어떻게 동작하는지 이해하는 것이 중요합니다. 시작하기 전 this는 호출한 주체라는 것을 기억하고, 이번 포스팅에서 예제와 함께 this를 확실하게 알아봅시다.

  • this에 대한 기본 개념을 파악
  • setTimeout 함수에서의 this 값 파악

🔧  JavaScript에서 this란?

this는 호출한 주체이다.

 

this는 객체이지만 문제는 이 this가 어떤 객체인지가 헷갈립니다. this의 값은 함수를 호출하는 방법에 의해 결정됩니다.

  • 호출한 주체가 없을 경우 기본값인 window가 객체가 됩니다. (전역 스코프가 window인 경우)
  • 화살표 함수 (Arrow Function)와 Strict Mode에서의 this는 달라집니다.

1. 기본적인 this의 동작

대부분의 경우 this는 함수를 호출하는 방법에 의해 결정됩니다. 가장 간단한 예제부터 시작해봅시다.

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

showThis(); // global 객체를 출력 (브라우저에서는 window 객체)

 

여기서 showThis 함수 내부의 this글로벌 객체를 참조합니다. 브라우저 환경에서는 window 객체가 됩니다. 함수가 전역에서 실행되기 때문에 this는 전역 객체(window)를 가리키게 되죠.

2. 객체 메서드 내의 this

이제 객체 안에서 this가 어떻게 동작하는지 살펴보겠습니다.

const person = {
  name: "John",
  greet: function () {
    console.log(this.name);
  },
};

person.greet(); // John

 

여기서 greet 메서드 내의 thisperson 객체를 참조합니다. 즉, this.nameperson.name을 출력하게 됩니다. this는 메서드가 호출되는 객체를 가리킵니다.

3. Strict Mode에서의 this

자바스크립트에서 Strict Mode는 코드의 실행 방식을 더 엄격하게 만들어 잠재적인 오류를 방지하는 기능입니다. 이 모드에서는 this의 동작이 몇 가지 중요한 차이점을 보입니다. 특히 전역 컨텍스트와 일반 함수 내부에서의 this가 undefined로 설정된다는 점이 큰 차이점입니다.

"use strict";

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

showThis(); // undefined , strict mode가 아닌 경우 브라우저 환경에서는 window 출력

 

strict mode에서 this는 의도치 않은 전역 객체 참조를 방지할 수 있습니다.

4. 화살표 함수에서의 this

화살표 함수는 this가 다르게 동작하는 경우입니다. 화살표 함수는 자신만의 this를 가지지 않고, 외부 스코프에서 this상속받습니다.

const person = {
  name: "John",
  greet: () => {
    console.log(this.name);
  },
};

person.greet(); // undefined

 

위 코드에서 thisgreet 메서드가 정의된 외부 스코프(문맥)를 가리킵니다. 전역에서 person.greet()을 호출하면, thiswindow 객체를 참조하게 되며, window.name은 정의되지 않았으므로 undefined가 출력됩니다.


🔧 call, apply, bindthis 변경하기

ES5에 도입된 call, apply, bind 메서드는 this를 명시적으로 설정할 수 있는 방법을 제공합니다. 이를 통해 우리가 원하는 객체를 this로 지정할 수 있습니다.

call 예제

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

const person = { name: "John" };
greet.call(person); // Hello, John

apply 예제

greet.apply(person); // Hello, John

 

callapply는 함수 실행 시 this를 특정 객체로 지정합니다. call은 인수들을 개별적으로 전달하는 방식이고, apply는 배열 형태로 전달하는 방식입니다.

bind 예제

const boundGreet = greet.bind(person);
boundGreet(); // Hello, John

bind는 새로운 함수 객체를 반환하며, 이 함수는 호출될 때 this가 고정됩니다. 즉, boundGreet는 항상 person 객체를 this로 사용합니다.


 🔧 setTimeout에서의 this

setTimeout 함수 내부의 this는 호출된 객체를 따르지 않고 기본적으로 전역객체(window나 global)를 가리키기 때문에 undefined나 window가 출력됩니다. Strict Mode에서는 기본적으로 전역 객체를(window)참조하지 않기 때문에 일반함수와 마찬가지고 undefined가 됩니다.

const obj = {
  name: "Alice",
  sayName: function () {
    setTimeout(function () {
      console.log(this.name); // undefined (브라우저에서는 window.name)
    }, 1000);
  },
};

obj.sayName();
"use strict";

setTimeout(function () {
  console.log(this); // undefined
}, 1000);

 

이 때 call, apply로 함수 실행시 this를 변경하거나 bind로 새로운 함수를 반환하여 this를 고정할 수 있습니다.

1. callthis 변경하기

const obj = {
  name: "Alice",
  sayName: function () {
    setTimeout(
      function () {
        console.log(this.name);
      }.call(this),
      1000
    ); // call을 사용하여 obj를 명시적으로 설정
  },
};

obj.sayName(); // Alice

 

 

call을 사용하면 즉시 this를 변경한 상태로 함수가 실행되므로, obj.name이 출력됩니다.


2. applythis 변경하기

applycall과 비슷하지만, 인수를 배열로 전달합니다.

const obj = {
  name: "Alice",
  sayName: function () {
    setTimeout(
      function () {
        console.log(this.name);
      }.apply(this),
      1000
    ); // apply를 사용하여 obj를 명시적으로 설정
  },
};

obj.sayName(); // Alice

3. bindthis 고정하기

bind는 새로운 함수를 반환하며, 해당 함수에서 this를 고정합니다.

const obj = {
  name: "Alice",
  sayName: function () {
    setTimeout(
      function () {
        console.log(this.name);
      }.bind(this),
      1000
    ); // bind를 사용하여 obj를 명시적으로 설정
  },
};

obj.sayName(); // Alice

bind는 즉시 실행하지 않고 setTimeout에 전달되는 함수의 this를 고정합니다.


4. 화살표 함수와 함께 사용하기

화살표 함수는 자신을 포함하고 있는 외부 스코프에서 this를 상속받기 때문에, 명시적으로 this를 변경하지 않아도 됩니다.

const obj = {
  name: "Alice",
  sayName: function () {
    setTimeout(() => {
      console.log(this.name);
    }, 1000); // 화살표 함수는 상위 컨텍스트의 this를 상속
  },
};

obj.sayName(); // Alice

🔧 클래스에서의 this

클래스에서 this는 해당 클래스의 인스턴스를 가리킵니다. 클래스 문법에서는 Strict Mode가 기본적으로 활성화되기 때문에 클래스 내에서 정의된 일반 메서드는 this가 undefined가 될 수 없으며, 항상 클래스의 인스턴스를 참조합니다.

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, ${this.name}`);
  }
}

const john = new Person("John");
john.greet(); // Hello, John

 

여기서 greet 메서드 내의 thisjohn 인스턴스를 참조합니다. 클래스에서 this는 항상 해당 클래스의 인스턴스를 가리킵니다.

결론은 this는 호출한 주체이다.

예제를 보았는데도 아직 헷갈린다면 "this = 호출한 주체" 라는 것을 기억하고 많은 코드 예시를 보면서 학습하는 것을 추천드립니다.

마무리 요약

  • 전역에서 this글로벌 객체를 가리킵니다.
  • 객체의 메서드 내에서 this메서드를 호출한 객체를 가리킵니다.
  • 화살표 함수는 자기 자신만의 this를 가지지 않으며, 화살표 함수가 선언된 곳인 외부 this를 상속받습니다.
  • call, apply, bindthis를 명시적으로 설정할 수 있습니다.
  • 클래스에서 this클래스의 인스턴스를 가리킵니다.

this의 동작을 이해하는 것은 자바스크립트의 중요한 개념 중 하나입니다. this호출한 주체라고 생각하며, 여러 상황에서 this가 어떻게 변하는지를 확실하게 파악하는 연습을 해보면 더 정확하고 효율적인 코드를 작성할 수 있게 될 것입니다.

참조

728x90