Published On

JavaScript의 this 바인딩 완벽 정리


JavaScript에서 this는 많이 등장하지만 헷갈리기 쉬운 개념입니다.

같은 코드라도 호출 방식에 따라 this의 값이 달라지는 것이 복잡하게 느껴질 수 있습니다.

이번 글에서는 다양한 상황에서의 this 동작을 간결한 예제를 통해 명확하게 이해해보겠습니다.


전역 문맥과 함수 호출에서의 this

console.log(this); // 브라우저에서는 window, Node.js에서는 global

function showThis() {
  console.log(this); // 브라우저에서는 window, strict 모드에서는 undefined
}
showThis();
  • 전역 문맥에서 this는 브라우저의 경우 window 객체를 참조합니다.
  • strict 모드에서는 일반 함수 내의 this가 undefined로 설정됩니다.

객체 메서드와 화살표 함수에서의 this

const obj = {
  name: "Alice",
  greet() {
    console.log(this.name); // "Alice" (this는 obj를 참조)

    setTimeout(function () {
      console.log(this.name); // undefined (전역 객체를 참조)
    }, 500);

    setTimeout(() => {
      console.log(this.name); // "Alice" (상위 스코프의 this 사용)
    }, 500);
  },
};
obj.greet();
  • 객체 메서드에서 this는 해당 객체를 참조합니다.
  • 일반 함수의 setTimeout에서는 전역 객체를 참조하지만, 화살표 함수상위 스코프의 this를 사용합니다.

생성자 함수와 클래스에서의 this

function Person(name) {
  this.name = name;
}
const person1 = new Person("Bob");
console.log(person1.name); // "Bob"

class Animal {
  constructor(type) {
    this.type = type;
  }
  showType() {
    console.log(`This animal is a ${this.type}`);
  }
}
const cat = new Animal("cat");
cat.showType(); // "This animal is a cat"
  • 생성자 함수와 클래스에서 this는 새로 생성된 인스턴스 객체를 가리킵니다.

명시적 바인딩: call, apply, bind

const person = { name: "Charlie" };
function sayName() {
  console.log(this.name);
}

sayName.call(person); // "Charlie" (call로 this 바인딩)
sayName.apply(person); // "Charlie" (apply도 동일)

const boundSayName = sayName.bind(person);
boundSayName(); // "Charlie" (bind로 바인딩된 함수 호출)
  • callapply는 함수를 즉시 실행하며, this를 바인딩합니다.
  • bind는 새로운 함수를 반환하고, 바인딩된 this를 유지합니다.

global 객체 vs window 객체

항목window 객체 (브라우저 환경)global 객체 (Node.js 환경)
역할브라우저의 전역 객체로, 모든 전역 변수와 함수를 담음Node.js의 전역 객체로, 모든 전역 API와 모듈을 관리
접근 방법window 또는 thisglobal 또는 this (최상위 스코프에서)
전역 변수 저장모든 전역 변수가 window 객체에 자동으로 저장됨전역 변수는 모듈 범위에 격리되며 자동으로 global에 추가되지 않음
DOM 접근document, location 등 DOM 관련 API 제공Node.js에서는 DOM이 없으므로 해당 API가 없음
타이머 APIsetTimeout, setInterval 등 제공setTimeout, setInterval 등 제공
네트워크 APIfetch API 제공최신 Node.js에서는 fetch가 기본 제공됨
기본 제공 기능alert, prompt, localStorage, sessionStorageconsole, process, Buffer 등 제공
이벤트 루프브라우저의 이벤트 루프를 통해 UI 업데이트 및 비동기 작업 처리Node.js의 이벤트 루프로 비동기 I/O 작업 처리
순환 참조순환 참조 없음global 객체 내부에 자기 자신(global)을 순환 참조
파일 시스템 접근파일 시스템에 직접 접근 불가fs 모듈로 파일 시스템에 접근 가능
  • 브라우저 환경은 사용자 인터페이스(UI)와 상호작용하기 위한 목적에 맞게 설계되었고, window 객체가 전역 객체로 사용됩니다.
  • Node.js 환경서버 측 작업과 비동기 I/O 처리를 위해 설계되었으며, global 객체가 전역 객체로 사용됩니다.
  • 두 환경의 가장 큰 차이점은 DOM의 유무파일 시스템 접근 여부입니다.
    • 브라우저는 DOM 조작을 지원하지만 파일 시스템 접근이 제한됩니다.
    • 반면, Node.js는 DOM이 없고, 파일 시스템 및 네트워크 접근을 중점으로 지원합니다.