this

this

  • 다른 대부분의 객체지향 언어에서 this는 클래스로 생성한 인스턴스 객체를 의미
  • 하지만 Js에서 this는 어디서든 사용할 수있음
  • 함수와 객체의 구분이 느슨한 JS에서 this는 실질적으로 이 둘을 구분하는 거의 유일한 기능

3-1 상황에 따라 달라지는 this

  • this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정
    • this는 함수를 호출할 때 결정된다
    • 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라짐

3-1-1 전역 공간에서의 this

  • 전역 공간에서 this는 전역 객체를 가리킴(개념상 전역 컨텍스트를 생성하는 주체가 전역객체임)
  • 전역 객체는 js 런타임 환경에 따라 다른 이름과 정보를 가지고 있음
    • 브라우저에서 window, Node.js에서 global
  • 전역 공간에서만 발생하는 특이한 성질
    • 전역변수를 선언하면 JS엔진은 전역객체의 프로퍼티로 할당.(변수이면서 객체의 프로퍼티)
    • JS의 모든 변수는 특정 객체의 프로퍼티로서 동작
      • 특정 객체란 실행 컨텍스트의 LexicalEnvironment(이하 L.E)
      • 실행 컨텍스트는 변수를 수집해서 L.E의 프로퍼티로 저장 (이후 어떤 변수든 호출하면 L.E를 조회해서 일치하는 프로퍼티가 있으면 값을 반환)
    • 전역 컨텍스트의 경우 L.E는 전역객체를 그대로 참조
  • 전역 공간에서는 변수 선언 대신 window의 프로퍼티에 직접 할당하더라도 대부분 선언과 똑같이 동작
    • but! 삭제 명령은 다름
    • 전역객체의 프로퍼티로 할당하면 삭제가 되는 반면 전역변수로 선언한 경우는 삭제가 되지 않는다.
  • var로 선언한 전역변수와 전역객체의 프로퍼티는 호이스팅 여부 및 confiqurable여부에서 차이

3-1-2 메서드로서 호출할 때 그 메서드 내부에서의 this

함수 vs 메서드

  • 프로그래밍 언어에서 함수와 메서드의 유일한 차이는 독립성
    • 함수: 그 자체로 독립적인 기능 수행
    • 메서드: 자신을 호출한 대상 객체에 관한 동작 수행
  • 어떤 함수를 객체의 프로퍼티로 할당한 경우 객체의 메서드로서 호출하는 경우에만 메서드로 동장, 그러지 않으면 함수로 동작
    • 원래의 익명 함수는 그대로인데 이를 변수에 담아 호출한 경우와 obj객체의 프로퍼티에 할당해서 호출한 경우의 this가 달라진다.
  • method앞에 점이 없으면 함수로서 호출, 있으면 메서드로서 호출

메서드 내부에서의 this

  • this에는 호출한 주체에 대한 정보가 담김
    • 점 표기법의 경우 마지막 점 앞에 명시된 객체가 곧 this

3-1-3 함수로서 호출할 때 그 함수 내부에서의 this

함수 내부에서의 this

  • 함수로서 호출하는 것은 호출 주체를 명시하지 않고 직접 코드에 관여
  • → 호출 주체의 정보를 알 수 없다.
  • this가 지정되지 않은 경우 함수에서의 this는 전역객체를 가리킴

메서드 내부 함수에서의 this

  • 내부함수 역시 함수로서 호출했는지 메서드로서 호출했는지 파악해야함.
  • this 바인딩에 관해서는 함수 실행하는 당시 주변 환경은 중요하지 않음!
    • 오직 해당 함수를 호출하는 구문 앞에 점 또는 대괄호 표기가 있는지 없는지가 중요

메서드 내부 함수에서의 this를 우회하는 방법

  • 호출 주체가 없을 때는 자동으로 전역객체를 바인딩하지 않고 호출 당시 주변 환경의 this를 그대로 상속 받았으면 한다.
    • 변수를 활용하자!
      • 상위 스코프의 this를 저장해서 내부함수에서 활용하려는 수단일 뿐

this를 바인딩하지 않는 함수

  • 함수 내부에서 this가 전역객체를 바라보는 문제를 보완하기 위해 나옴
    • 화살표 함수: this를 바인딩하지 않음 → 우회법이 필요하지 않아짐
    • 그 밖에도 call, apply 등 명시적으로 this를 지정하는 방법

3-1-4 콜백 함수 호출 시 그 함수 내부에서의 this

  • 제어권을 받은 함수에서 콜백함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조
    • 지정하지 않을 경우 전역객체를 참조

3-1-5 생성자 함수 내부에서의 this

  • 생성자 함수: 어떤 공통된 성질을 지니는 객체들을 생성하는데 사용하는 함수
  • 객체 지향 언어
    • 생성자: 클래스(구체적인 인스턴스를 만들기 위한 일종의 틀)
    • 클래스를 통해 만든 객체: 인스턴스
  • new 명령어와 함께 함수를 호출 → 해당 함수가 생성자로서 동작
    • 함수가 생성자 함수로서 호출된 경우
      • 내부에서의 this === 새로 만들 구체적인 인스턴스 자신

3-2 명시적으로 this를 바인딩하는 방법

3-2-1 call 메서드

  • call메서드: 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령
    • 첫번째 인자를 this로 바인딩하고, 이후의 인자들을 호출할 함수의 매개변수로 한다.
      • 함수를 그냥 실행 → this는 전역객체를 참조
      • 메서드를 그냥 호출 → this는 객체를 참조
      • call 메서드를 이용 → 임의의 객체를 this로 지정 가능

3-2-2 apply 메서드

  • apply 메서드: call메서드와 기능적으로 완전히 동일
    • call: 첫 번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정
    • apply: 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정

3-2-3 call/apply 메서드의 활용

유사배열객체에 배열 메서드를 적용

  • 키가 0또는 양의 정수인 프로퍼티가 존재하고, length 프로퍼티의 값이 0또는 양의 정수인 객체(배열의 구조와 유사한 객체)인 경우 call또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있다.
    • 유사배열객체 또는 순회 가능한 모든 종류의 데이터 타입을 배열로 전환하는 Array.from 메서드가 도입 되었음.

생성자 내부에서 다른 생성자를 호출

  • 생성자 내부에 다른 생성자와 공통된 내용이 있을 경우 call/apply를 이용해 다른 생성자를 호출 할 수 있음

여러 인수를 묶어 하나의 배열로 전달하고 싶을 때 - apply 활용

3-2-4 bind 메서드

  • call 과 비슷하지만 즉시 호출하지는 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 하는 메서드
    • 다시 새로운 함수를 호출할 때 인수를 넘기면 그 인수들은 기존 bind 메서드를 호출할 때 전달했던 인수들의 뒤에 이어서 등록됨.
  • bind 메서드의 목적
    • 함수에 this를 미리 적용하는 것
    • 부분 적용 함수를 구현하는 것

name 프로퍼티

  • bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 ‘bound’ 접두어가 붙는다.
    • bound 접두어가 붙어 있으면 원본함수에 bind메서드를 적용한 새로운 함수라는 뜻

상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기

  • 콜백 함수를 인자로 받는 함수나 메서드 중에서 기본적으로 콜백 함수 내에서의 this에 관여하는 함수 또는 메서드에 대해서도 bind 메서드를 이용해 this 값을 사용자의 입맛에 맞게 바꿀 수 있음

3-2-5 화살표 함수의 예외사항

  • 화살표 함수의 내부에는 this가 아예 없음
    • 접근하고자 하면 스코프체인상 가장 가까운 this에 접근하게 된다.

3-2-6 별도의 인자로 this를 받는 경우(콜백 함수 내에서의 this)

  • 콜백 함수 내부에서 this 값을 원하는대로 변경 가능
  • 이러한 형태는 배열 메서드에 많이 포진

정리

다음 규칙은 명시적 this 바인딩이 없는 한 늘 성립

  • 전역공간에서의 this는 전역객체를 참조
  • 어떤 함수를 메서드로서 호출한 경우 this는 메서드 호출 주체를 참조
  • 어떤 함수를 함수로서 호출한 경우 this는 전역객체를 참조. 메서드 내부함수도 동일
  • 콜백 함수 내부에서의 this는 해당 콜백 함수의 제어권을 넘겨받은 함수가 정의한 바에 따르며, 정의하지 않은 경우에는 전역객체를 참조
  • 생성자 함수에서의 this는 생성될 인스턴스를 참조

위 규칙에 부합하지 않는 경우에는 다음 내용을 바탕으로 this를 예측할 수 있다.

  • call, apply메서드는 this를 명시적으로 지정하면서 함수 또는 메서드를 호출
  • bind메서드는 this 및 함수에 넘길 인수를 일부 지정해서 새로운 함수를 만듦
  • 요소를 순회하면서 콜백 함수를 반복 호출하는 내용의 일부 메서드는 별도의 this를 받기도 함.
profile
프론트엔드 개발자 루루

0개의 댓글