seunghyun Note

22장 (this) 본문

스터디/모던자바스크립트 deep dive

22장 (this)

승숭슝현 2024. 1. 8. 10:33

1. this 키워드

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

동작을 나타내는 메서드는 자신이 속한 객체의 상태, 즉 프로퍼티를 참조하고 변경할 수 있어야 한다. 이때 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 하는데, 이때 this를 사용한다.

const circle = {
  // 프로퍼티: 객체 고유의 상태 데이터
  radius: 5,
  // 메서드: 상태 데이터를 참조하고 조작하는 동작
  getDiameter() {
    // 이 메서드가 자신이 속한 객체의 프로퍼티나 다른 메서드를 참조하려면
    // 자신이 속한 객체인 circle을 참조할 수 있어야 한다.
    return 2 * circle.radius;
  }
};

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

getDiameter메서드 내에서 메서드 자신이 속한 객체를 가리키는 식별자 circle을 참조하고 있다.

실행되는 순서

변수 호이스팅으로 circle 변수 생성(초기화는X)
circle변수에 할당되기 직전에 객체 리터럴을 평가
circle객체 생성
circle.getDiameter();즉, getDiameter메서드가 호출되어 함수 몸체가 실행된다.
getDiameter메서드가 실행될 때 circle식별자를 참조한다.
circle.getDiameter();호출하는 시점에는 이미 circle객체가 생성되어 있으므로 메서드 내부에서 circle식별자를 참조할 수 있다.


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

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

// 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수를 정의해야 한다.
const circle = new Circle(5);

2.함수 호출 방식과 this 바인딩

※ 렉시컬 스코프와 this 바인딩은 결정 시기가 다르다.
렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 결정된다.
this는 함수가 호출시에 결정된다.

※ 함수 객체가 생성되는 시점
함수 선언문은 코드(함수 선언문을 포함한) 평가 단계에서 함수 객체 생성
함수 표현식은 코드(함수 표현식을 포함한) 실행 단계에서 함수 객체 생성

함수를 호출하는 다양한 방식

일반 함수 호출
메서드 호출
생성자 함수 호출
Function.prototype.apply/call/bind메서드에 의한 간접 호출

// this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다.
const foo = function () {
  console.dir(this);
};

// 동일한 함수도 다양한 방식으로 호출할 수 있다.

// 1. 일반 함수 호출
// foo 함수를 일반적인 방식으로 호출
// foo 함수 내부의 this는 전역 객체 window를 가리킨다.
foo(); // window

// 2. 메서드 호출
// foo 함수를 프로퍼티 값으로 할당하여 호출
// foo 함수 내부의 this는 메서드를 호출한 객체 obj를 가리킨다.
const obj = { foo };
obj.foo(); // obj

// 3. 생성자 함수 호출
// foo 함수를 new 연산자와 함께 생성자 함수로 호출
// foo 함수 내부의 this는 생성자 함수가 생성한 인스턴스를 가리킨다.
new foo(); // foo {}

// 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
// foo 함수 내부의 this는 인수에 의해 결정된다.
const bar = { name: 'bar' };

foo.call(bar);   // bar
foo.apply(bar);  // bar
foo.bind(bar)(); // bar

3. 정리

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

'스터디 > 모던자바스크립트 deep dive' 카테고리의 다른 글

24장 (클로저)  (0) 2024.01.08
23장 (실행 컨텍스트)  (1) 2024.01.08
21장 (빌트인 객체)  (0) 2024.01.08
20장(strict mode)  (0) 2024.01.08
19장(프로토타입)  (1) 2024.01.08