JavaScript - this

치맨·2023년 1월 15일
0

javascript

목록 보기
7/23
post-thumbnail

목차

this란

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

  • 자기자신을 가리킨다? 그냥 자기자신을 가리키면 되지 왜 굳이 this를 사용해줄까? 라는 의문이 생겼습니다.
    => 객체 리터럴 방식에선 자기자신을 가리키는 식벽자를 참조할 수 있습니다. 하지만 자기자신이 속한 객체를 재귀적으로 참조하는 방식은 일반적이지 않으며 바람직하지도 않습니다.

    => 왜 why? 인스턴스를 생성하려면 먼저 생성자 함수가 존재해야하고, 생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자는 알 수가 없기 때문입니다.
    자바스크립트에선 자기가 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자를 사용하기 위해 this를 제공합니다.

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

  • 단 this의 값은 함수를 호출한 방법에 의해 동적으로 결정됩니다. 여기서 가장 중요한 부분은 호출 방법에 의해 이 부분입니다.


this 호출 방법

호출 방법이 중요하다? 그렇다면 호출방법에 대해 4가지를 알아보겠습니다.

일반 함수 호출

 - 일반함수로 호출할 경우 함수 내부의 this에는 `전역객체(window)가 바인딩 됩니다.`
 - 이때 중첩함수, 콜백함수의 내부에서 또한 전역객체가 바인딩 됩니다. 

단 strict mode의 경우 undefined가 바인딩 됩니다.

메서드 호출

  • 메서드 내부의 this는 호출한 객체에 바인딩 됩니다.
    1. car.getBrand()할 경우 car객체에서 호출 했기 때문에 Car객체가 바인딩됩니다.
    1. audi.getBrand()할 경우 audi객체에서 호출 했기 때문에 audi객체가 바인딩 됩니다.
    1. benz.getBrand()할 경우 benz객체에서 호출 했기 때문에 benz객체가 바인딩 됩니다.
    1. globalCar()를 호출할 경우 전역에서 호출했기 때문에 window객체가 바인딩 됩니다.

생성자 함수 호출

 - 생성자 함수 내부의 this에는 `(미래에) 생성할 인스턴스가 바인딩 됩니다.`

1. circle1에 radius로 10을 전달하여 circle1의 radius는 10이 바인딩 되며, getDiameter()를 호출하면 20이 출력 됩니다.

2. circle2에 radius로 20을 전달하여 circle2의 radius는 20이 바인딩 되며, getDiameter()를 호출하면 40이 출력 됩니다.

3. circle3에 radius로 30을 전달하여 circle3의 radius는 30이 바인딩 되며, getDiameter()를 호출하면 60이 출력 됩니다.

apply,call,bind메소드에 의한 간접 호출

 - 3가지 모두 첫번째 인자로 전달한 값을 this에 바인딩 할 수 있습니다.
- apply, call 메소드의 본직적인 기능은 함수를 호출하는 것입니다.
 - bind메소드는 첫 번째 인수로 전달한 값으로 this바인딩이 교체된 함수를 새롭게 생성하여 반환합니다. 

apply 사용

  • 본질적인 기능은 함수를 호출하는 것 입니다.
  • 첫번째 인수로 전달한 특정 객체를 호출한 함수의 this에 바인딩 합니다.
  • 호출할 함수의 인수를 배열로 묶어 전달합니다.

call 사용

  • 본질적인 기능은 함수를 호출하는 것 입니다.
  • 첫번째 인수로 전달한 특정 객체를 호출한 함수의 this에 바인딩 합니다.
  • 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달합니다.

bind 사용

  • apply와 call 메서드와 달리 함수를 호출하지 않습니다.

  • 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환합니다.

  • 메서드의 this와 메서드 내부의 중첩 함수 또는 콜백 함수의 this가 불일치 하는 문제를 해결하기 위해 유용하게 사용됩니다.

  • 아래의 사진을 보면 callback 함수가 호출되기 이전 시점에서는 this가 person객체를 가리킵니다.

  • 하지만 콜백함수가 일반 함수로 호출된 시점에서 this는 전역객체(window)를 가리키게 되고, window.name === this.name의 결과가 true로 나타남을 확인할 수 있습니다.

  • 콜백함수를 호출하는 시점의 this와 외부 함수 내부의 this를 일치시키기 위해 bind 메서드를 사용해서 일치시킬 수 있습니다.

  • 따라서 아래의 사진과 같이 bind를 통해 this.name이 window가 아닌 person객체의 name과 동일하도록 일치시킴을 확인할 수 있었습니다.


화살표함수의 this

  • 화살표함수는 함수 자체의 this바인딩을 갖지 않습니다.
  • 따라서 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조합니다. 이를 lexical this 라고 합니다.
  • 만약 화살표함수의 상위스코프가 화살표함수라면? 그렇다면 또 상위 스코프를 참조합니다.
  • 즉 화살표함수의 this는 가장 가까운 상위함수 중 화살표 함수가 아닌 함수의 this를 참조합니다.

  • 왼쪽 사진은 화살표 함수를 사용했기 때문에 this가 상위 스코프인 전역객체를 가리키기 때문에 undefined가 출력이 됩니다.
  • 오른쪽 사진은 화살표함수를 사용하지 않았기 때문에 상위스코프가 아닌 person객체의 name을 가리키기 때문에 'KIM'이 출력 됩니다.

정리

  • this란 자기참조 변수이며, 호출되는 방식에 따라 this 바인딩이 동적으로 결정됩니다.

  • 일반함수에서 호출한 경우 전역객체(window)가 바인딩 됩니다. 단 strict 모드일 경우 undefined가 바인딩 됩니다.

  • 메서드 내부의 this는 호출한 객체가 바인딩 됩니다.

  • 생성자 함수 내부의 this에는 (미래에) 생성할 인스턴스가 바인딩 됩니다.

  • apply, call, bind 메서드는 공통적으로 인수로 전달한 객체를 호출한 함수의 this에 바인딩 하기 위해 사용하는 공통적인 부분이 있습니다.

    • apply, call 메서드는 공통적으로 본질적인 기능이 함수를 호출하는 것이며, 첫번째 인수로 전달할 객체를 전달하고 두번째 인수로 호출할 함수의 인수를 전달 하는 것입니다.

    • 하지만 apply는 인수를 배열로 묶어서 전달하고, call은 쉼표로 구분한 리스트 형식으로 전달합니다.

    • bind의 경우 함수를 호출하진 않지만 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환합니다. 메서드의 this와 메서드 내부의 중첩함수 또는 콜백함수의 this가 불일치 하는 문제를 해결하기 위해 유용하게 사용됩니다.


Ref

profile
기본기가 탄탄한 개발자가 되자!

0개의 댓글