JS this 키워드

배경

객체는 상태(state)를 나타내는 프로퍼티와 동작(behavior)을 나타내는 메서드를 하나의 논리적인 단위로 묶은 복합적인 자료구조다.

메서드는 프로퍼티를 참조하고 변경할 수 있어야 한다. 이때 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.

그런데 생성자 함수 방식으로 인스턴스를 생성하는 경우를 생각해보면 먼저 생성자 함수가 존재해야 한다.

function Circle(radius) {
    // 이 시점에서 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
    ??.radius = radius;
}

Circle.prototype.getDiameter = function() {
    // 이 시점에서 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
    return 2 * ??.radius;
}

const circle = new Circle(5);

생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없다. 따라서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요하다. 이를 위해 JS는 this 식별자를 제공한다.

function Circle(radius) {
  this.radius = radius;
}

Circle.prototype.getDiameter = function () {
  return 2 * this.radius;
};

const circle = new Circle(5);

console.log(circle.getDiameter()); // 10

this 바인딩

this 바인딩(this에 바인딩될 값)은 함수 호출 방식, 즉 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다.

const foo = function () {
  console.dir(this);
};

// 1. 일반 함수 호출
foo(); // window

// 2. 메서드 호출 : foo 함수를 프로퍼티 값으로 할당하여 호출
const obj = { foo };
obj.foo(); // obj

// 사용법
const Circle = {
  radius: 5,
  getDiameter() {
    return 2 * this.radius;
  },
};

// 3. 생성자 함수 호출 : foo 함수를 new 연산자와 함께 생성자 함수로 호출
new foo(); // foo {}

// 사용법
function Circle(radius) {
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}
const circle = new Circle(5);

// 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
const bar = { name: "bar" }; // this로 사용할 객체
foo.call(bar); // bar
foo.apply(bar); //bar
foo.bind(bar)(); // bar

정리

함수 호출 방식 this 바인딩
일반 함수 호출 전역 객체
메서드 호출 메서드를 호출한 객체
생성자 함수 호출 생성자 함수가 (미래에) 생성할 인스턴스
Function.prototype.apply/call/bind 메서드에 의한 간접 호출 Function.prototype.apply/call/bind 메서드에 첫 번째 인수로 전달한 객체

출처 :

카테고리:

업데이트:

댓글남기기