this 알아보기 [모던 자바스크립트 Deep Dive : 22장]

조성원·2023년 4월 4일
0
post-thumbnail

객체 - 프로퍼티와 메서드

객체
상태를 나타내는 프로퍼티
동작을 나타내는 메서드
하나의 단위로 묶은 자료구조입니다.

메서드는
프로퍼티를 참조하고 변경할 수 있어야 합니다.

그러기 위해서는,
자신이 속한 객체를 가리키는 식별자(변수)를 참조해야 합니다.

객체와 식별자를 연결하는 작업이 필요하고,
여기서 this를 통해 연결하게 됩니다.






this

this는
자신이 속한 객체
또는 자신이 생성할 인스턴스
가리키는 자기 참조 변수입니다.

this를 통해
자신이 속한 객체 또는 자신이 생성할 인스턴스의
프로퍼티나 메서드를 참조할 수 있다.

this는 자바스크립트 엔진에 의해 암묵적으로 생성되며,
코드 어디서든 참조할 수 있습니다.






this 바인딩

바인딩이란
식별자(변수)와 (원시 값 또는 객체)을
연결하는 과정을 의미합니다.

예를 들어, 변수 선언
변수 이름(식별자)과 확보된 메모리 공간의 주소
바인딩하는 것이다.

this 바인딩
this(키워드로 분류되지만 식별자 역할을 함)와
this가 가리킬 객체를 바인딩하는 것입니다.

예시를 통해 알아보겠습니다.

// 객체 리터럴
const circle(radius) = {
  radius = 5;
  getDiameter = function() {
    // this는 메서드를 호출한 객체를 가리킨다.
    return 2 * this.radius;
  }
};

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

여기서 this는 메서드를 호출한 객체, 즉 circle을 가리킵니다.






함수 호출 방식과 this 바인딩

this 바인딩은
함수 호출 방식에 따라
동적으로 결정됩니다.

정리하면, 크게 4가지로 분류할 수 있습니다.

  • 함수(일반, 콜백, 내부) 호출: 전역 객체(window/ global)

  • 메서드 호출: 메서드를 호출한 객체

  • 생성자 함수 호출: 생성자 함수가 (미래에) 생성할 인스턴스

  • Function.prototype.apply/call/bind 메서드에 의한 간접 호출:
    메서드에 첫 번째 인수로 전달한 객체


코드를 보면서 알아보겠습니다.

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

// 1. 일반 함수 호출 > 전역 객체 window를 가리킴
foo(); // window

// 2. 메서드 호출 > 메서드를 호출한 객체를 가리킴
const obj = { foo };
obj.foo(); // obj

// 3. 생성자 함수 호출 > 생성자 함수가 생성한 인스턴스를 가리킴
new foo() // foo{}

// 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출 
// > 객체를 가리킴
const bar = { name: 'bar' }
foo.call(bar); // Object
foo.apply(bar); // Object
foo.bind(bar)(); // Object

콜백 함수에서
this 바인딩을 메서드의 this 바인딩과
일치시키기 위한 방법은 다음과 같습니다.

const obj = {
  value: 100,
  foo() {
    // bind라는 메서드를 통해 명시적으로 this를 바인딩함
    setTimeout(function() {
      console.log(that.value); // 100
    }.bind(this), 100);
  };
};

obj.foo();

또는

const obj = {
  value: 100,
  foo() {
    // 화샬표 함수 내부의 this는 상위 스코프의 this를 가리킴
    setTimeout(() => console.log(this.value); // 100
    }, 100);
  };
};

obj.foo();
profile
IT 트렌드에 관심이 많은 프론트엔드 개발자

0개의 댓글