icon안동민 개발노트

This 키워드와 바인딩


 자바스크립트에서 this 키워드는 현재 실행 컨텍스트를 참조하는 특별한 식별자입니다.

 this의 값은 함수가 호출되는 방식에 따라 동적으로 결정되며, 이는 자바스크립트의 유연성을 높이지만 동시에 혼란의 원인이 되기도 합니다.

this의 기본 동작

 this의 값은 함수가 어떻게 호출되었는지에 따라 달라집니다.

  1. 전역 실행 컨텍스트
  • 전역 스코프에서 this는 전역 객체(브라우저에서는 window, Node.js에서는 global)를 가리킵니다.
console.log(this === window); // 브라우저에서 true
  1. 함수 호출
  • 일반 함수 호출에서 this는 전역 객체를 가리킵니다(strict mode에서는 undefined).
function showThis() {
  console.log(this);
}
showThis(); // window 또는 global
  1. 메서드 호출
  • 객체의 메서드로 호출될 때 this는 해당 객체를 가리킵니다.
const obj = {
  name: "MyObject",
  sayHello: function() {
    console.log("Hello, " + this.name);
  }
};
obj.sayHello(); // "Hello, MyObject"
  1. 생성자 함수 호출
  • new 키워드로 호출된 함수에서 this는 새로 생성된 객체를 가리킵니다.
function Person(name) {
  this.name = name;
}
const john = new Person("John");
console.log(john.name); // "John"

명시적 this 바인딩

 자바스크립트는 this를 명시적으로 바인딩할 수 있는 메서드를 제공합니다.

  1. call
  • 첫 번째 인자로 this를 바인딩하고, 나머지 인자들을 함수의 매개변수로 전달합니다.
function greet(greeting) {
  console.log(greeting + ", " + this.name);
}
const person = { name: "Alice" };
greet.call(person, "Hello"); // "Hello, Alice"
  1. apply
  • call과 유사하지만, 함수의 매개변수를 배열로 전달합니다.
greet.apply(person, ["Hi"]); // "Hi, Alice"
  1. bind
  • 새로운 함수를 반환하며, 이 함수는 지정된 this 값으로 영구적으로 바인딩됩니다.
const boundGreet = greet.bind(person);
boundGreet("Hey"); // "Hey, Alice"

화살표 함수에서의 this

 화살표 함수는 자신만의 this를 가지지 않고, 렉시컬 스코프의 this를 사용합니다.

const obj = {
  name: "MyObject",
  regularFunction: function() {
    console.log(this.name);
  },
  arrowFunction: () => {
    console.log(this.name);
  }
};
 
obj.regularFunction(); // "MyObject"
obj.arrowFunction(); // undefined (전역 객체의 name)

 화살표 함수는 this를 바인딩하지 않기 때문에, 객체의 메서드로 사용할 때 주의가 필요합니다.

this 관련 흔한 실수와 해결 방법

  1. 콜백 함수에서의 this 손실
const obj = {
  name: "MyObject",
  doSomething: function() {
    setTimeout(function() {
      console.log(this.name);
    }, 1000);
  }
};
obj.doSomething(); // undefined

 해결 방법

  • 화살표 함수 사용
  • bind 메서드 사용
  • that = this 패턴 사용
  1. 메서드를 변수에 할당
const obj = {
  name: "MyObject",
  sayHello: function() {
    console.log("Hello, " + this.name);
  }
};
const say = obj.sayHello;
say(); // "Hello, undefined"

 해결 방법

  • bind 메서드 사용
  • 메서드를 호출할 때 객체 참조 유지

객체 지향 프로그래밍에서의 this

 객체 지향 프로그래밍에서 this는 현재 객체의 인스턴스를 참조하는 데 사용됩니다.

function Car(make, model) {
  this.make = make;
  this.model = model;
  this.displayInfo = function() {
    console.log(`This car is a ${this.make} ${this.model}`);
  };
}
 
const myCar = new Car("Toyota", "Corolla");
myCar.displayInfo(); // "This car is a Toyota Corolla"

 this를 통해 객체의 속성과 메서드에 접근할 수 있어, 재사용 가능한 코드를 작성할 수 있습니다.

this를 활용한 디자인 패턴

  1. 메서드 체이닝
class Calculator {
  constructor() {
    this.value = 0;
  }
  add(n) {
    this.value += n;
    return this;
  }
  subtract(n) {
    this.value -= n;
    return this;
  }
  result() {
    return this.value;
  }
}
 
const calc = new Calculator();
console.log(calc.add(5).subtract(2).add(10).result()); // 13
  1. 모듈 패턴
const myModule = (function() {
  let privateVar = 0;
  
  return {
    increment: function() {
      privateVar++;
      console.log(this);
      return this;
    },
    decrement: function() {
      privateVar--;
      return this;
    },
    value: function() {
      return privateVar;
    }
  };
})();
 
console.log(myModule.increment().increment().value()); // 2

 this 키워드는 자바스크립트의 핵심 개념 중 하나로, 함수가 어떻게 호출되었는지에 따라 동적으로 바인딩됩니다.

 이러한 동적 바인딩은 코드의 재사용성과 유연성을 높이지만, 동시에 예측하기 어려운 동작을 야기할 수 있습니다.

 this의 값을 정확히 예측하고 제어하기 위해서는 함수 호출 방식, 명시적 바인딩 메서드(call, apply, bind), 그리고 화살표 함수의 특성을 잘 이해해야 합니다.

 특히 콜백 함수나 이벤트 핸들러에서 this를 사용할 때는 주의가 필요합니다.

 객체 지향 프로그래밍에서 this는 객체의 현재 인스턴스를 참조하는 데 사용되며, 이를 통해 메서드 내에서 객체의 속성과 다른 메서드에 접근할 수 있습니다.

 이는 코드의 재사용성과 유지보수성을 높이는 데 도움이 됩니다.

 this를 효과적으로 활용하면 메서드 체이닝, 모듈 패턴 등 다양한 디자인 패턴을 구현할 수 있습니다.

 이러한 패턴들은 코드의 가독성을 높이고 더 표현력 있는 API를 설계하는 데 도움이 됩니다.

 결론적으로, this 키워드와 바인딩을 정확히 이해하고 적절히 사용하는 것은 효과적인 자바스크립트 프로그래밍을 위해 필수적입니다.

 이는 단순히 언어의 특성을 아는 것을 넘어서 더 유연하고 강력한 코드를 작성할 수 있게 해주는 도구입니다.