this

Hyeon·2021년 10월 17일
0

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

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

함수 호출은 다음과 같이 이루어질 수 있다.

  1. 일반함수 호출
  2. 메서드 호출
  3. 생성자 함수 호출
  4. apply/call/bind 메서드에 의한 호출

일반함수 호출

일반 함수로 호출된 모든 함수 내부의 this에는 전역객체가 바인딩 된다.

function f() {//함수
  console.log(this);//window
}

function f2() {//중첩함수
  function inner() {
    console.log(this);//window
  }
  inner();
}

function f3() {//콜백함수
  setTimeout(() => {
    console.log(this);//window
  }, 1000);
}

f();
f2();
f3();

문제점

일반 함수로 호출 시 this에 전역객체가 바인딩 되기 때문에 의도한 결과가 나오지 않을 수 있다.

const obj = {
  value: 10,

  func: function () {
    setTimeout(function () {
      console.log(this.value);//undefined
    }, 1000);
  },
};

obj.func();

10을 출력하고 싶었지만, this가 전역객체를 가리키고 있기 때문에 해당 값이 존재하지 않는다.

문제를 해결해보자.

함수 호출 전 this를 저장해두고 사용

const obj = {
  value: 10,

  func: function () {
    const bind_this = this;

    setTimeout(function () {
      console.log(bind_this.value);//10
    }, 1000);
  },
};

obj.func();

뒤에서 다시 살펴보겠지만 func은 메서드이기 때문에 this에는 obj가 바인딩 된다. 이 값을 저장하고 콜백함수에서 사용한다.

apply/call/bind 사용

우선 bind만 간략하게 살펴보자.

const obj = {
  value: 10,

  func: function () {
    setTimeout(
      function () {
        console.log(this.value);//10
      }.bind(this),
      1000
    );
  },
};

obj.func();

위 예제를 이해했다면 이것도 쉽게 이해할 수 있다. bind 함수를 사용해서 func함수의 this를 콜백함수의 this와 연결한다.

화살표함수

가장 간단한 방법이다. function 키워드 대신 화살표 함수를 사용한다.

const obj = {
  value: 10,

  func: function () {
    setTimeout(() => {
      console.log(this.value);//10
    }, 1000);
  },
};

obj.func();

메서드 호출

메서드 내부의 this에는 메서드를 호출한 객체가 바인딩 된다.

const obj = {
  value: 10,

  func: function () {
    console.log(this); //{value: 10, func: ƒ}
  },
};

obj.func();

생성자 함수 호출

생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩된다.

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

  this.getRadius = function () {
    console.log(this.radius);//2
  };
}

const c1 = new Circle(2);
c1.getRadius();

apply/call/bind

apply,call,bind 메서드는 Function.prototype의 메서드이다.

apply와 call 메서드의 본질적인 기능은 함수를 호출하는 것이다. apply와 call메서드는 함수를 호출하면서 첫 번째 인수로 전달한 객체를 호출한 함수의 this에 바인딩한다.

반면 bind는 메서드를 호출하지는 않는다.

function bindPrint() {
  console.log(arguments);
  console.log(this.value);
}

const applyObj = {
  value: 1,
};

const callObj = {
  value: 10,
};

const bindObj = {
  value: 100,
}

bindPrint.apply(applyObj, [1, 2, 3]);
//[Arguments] { '0': 1, '1': 2, '2': 3 }
//1

bindPrint.call(callObj, [1, 2, 3]);
//[Arguments] { '0': [ 1, 2, 3 ] }
//10

bindPrint.bind(bindObj)();
//[Arguments] {}
//100

0개의 댓글