티스토리 뷰

this의 필요성

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

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

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

 

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

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

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

 

자기 자신이 속한 객체를 재귀적으로 참조하는 방식은 일반적이지 않으며 바람직하지 않다.

생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없다. 

  인스턴스 : 생성자 함수가 생성한 객체

 

 

this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-referencing variable)다.

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

 

this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

  바인딩 : 식별자와 값을 연결하는 과정

  this바인딩 : this와 this가 가리킬 객체를 연결하는 과정.

 

함수호출방식의 종류에 따른 this값

  1. 일반 함수 호출 - window

  2. 메서드 호출 - this를 호출한 객체

  3. 생성자 함수 호출 - 생성자 함수가 생성한 인스턴스

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

  5. 화살표 함수 호출 - 상위 스코프의 this를 가리킨다

 

2번 메서드 호출 안에서 일반 함수를 호출했을 때 일반 함수 안에서의 this는 무엇을 가리킬까?

 

정답 : window, 일반 함수로 호출된 모든 함수(중첩 함수, 콜백 함수 포함) 내부의 this에는 전역 객체가 바인딩된다.

var value = 1;

const obj = {
  value : 100, 
  foo() {
  console.log("foo's this : ", this); // {value: 100, foo: f} f는 함수를 의미
  // 콜백 함수 내부의 this에는 전역 객체가 바인딩된다.
  setTimeout(function(){
    console.log("callback's this: ", this); // window
    console.log("callback's this.value : " , this.value); // 1
  }, 100);
 }
};

obj.foo();

 

 

setTimeout 콜백 함수 안에서 this를 window객체가 아닌 foo()메서드의 this객체를 가리키게 하려면 어떻게 해야할까?

 

1. foo() 메서드에서 this를 변수에 할당해서 콜백함수 내부에서 변수를 참조한다.

var value = 1;

const obj = {
  value : 100, 
  foo() {
    // this 바인딩(obj)을 변수 that에 할당한다.
  const that = this;
  
  setTimeout(function(){
    // 콜백함수 내부에서 this 대신 that을 참조한다.
    console.log(that.value); // 100
    }, 100);
  }
};

obj.foo();

2. 콜백함수에 명시적으로 this를 바인딩한다.

var value = 1;

const obj = {
  value : 100, 
  foo() {
  // 콜백 함수에 명시적으로 this를 바인딩한다.
  setTimeout(function(){
    console.log(that.value); // 100
    }.bind(this), 100);
  }
};

obj.foo();

3. 화살표 함수를 사용한다.

var value = 1;

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

obj.foo();