this

Ordinary·2023년 5월 22일
0

this란,

자바스크립트에서의 this는 호출한 주체에 대한 정보를 담고 있습니다. this를 상황마다 다르게 지정될 수 있으며, 함수와 객체의 메서드에 대해 구분할 수 있는 기준으로 사용할 수도 있습니다.
자바스크립트에서는 실행 컨텍스트가 생성될 때 즉, 함수가 호출될 때, this가 결정됩니다.

클래스를 통해 생성된 인스턴스의 경우, 생성된 자기자신을 가리킵니다.

서로 다른 상황에서의 this

  1. 전역 공간
    전역 공간에서의 this는 전역객체를 가리킵니다. 즉, 브라우저 환경에서는 window객체를 가리키고 Node.js 환경에서는 global가 됩니다.
    전역 공간에서의 특이한 성질 중에 하나는 전역 변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다는 것입니다. 즉, a, window.a, this.a를 해도 같은 값을 얻을 수 있습니다.
    var a = 1;
    console.log(a);
    console.log(window.a);
    console.log(this.a);
  1. 함수와 메서드
    함수와 메서드의 차이는 독립적으로 호출되었는지, 객체의 메서드로 호출되었는지의 차이입니다.
    즉, 점 표기법이든 대괄호 표기법이든, 어떤 함수를 호출할 때, 함수 앞에 객체가 명시되어 있으면 메서드로 호출한 것이고, 그렇지 않은 모든 경우는 독립된 함수로 호출한 것입니다.
  • 객체의 메서드로 호출한 경우
    함수명 앞의 명시된 객체가 this가 됩니다.
  • 함수로 호출한 경우
    this가 지정되지 않기 때문에 호출하는 주체는 전역 객체가 됩니다.
    //일반 함수 func에는 전역객체가 this에 할당됨.
    function func() {
      console.log(this);
    }

    func(); // <ref *1> Object [global] { ... } or Window { ... }
  1. 콜백 함수 내부에서는 호출한 함수의 내부 로직에 따라 달라집니다.
    기본적으로는 전역객체를 바라보고 있지만 호출한 함수에서 별도로 this를 지정해서 콜백함수를 호출하는 경우 해당 대상을 참조하게 됩니다.
    ex) addEventListener 함수의 경우, 콜백 함수를 호출할 때 자신의 this를 상속하도록 되어있습니다.
  2. 생성자 내부에서의 this
    생성자는 구체적인 인스턴스를 만들기 위한 일종의 틀로써, 해당 클래스의 공통 속성들을 지정할 수 있습니다.
    자바스크립트는 new 키워드와 함께 함수를 호출하면 해당 함수가 생성자로써 동작하게 되는데, 이 때 this는 새로 만들어지는 인스턴스 자신이 됩니다.

this를 우회하는 방법

var obj1 = {
  outer: function() {
  	...
  	var innerFunc = function() {
  		console.log(this);
  	}
  	innerFunc();
  }
}
obj.outer();

다음과 같이 innerFuncobj1안의 outer필드의 함수 내부에서 정의되었지만 innerFunc() 호출 자체가 어떤 객체가 명시되지 않은 독립적인 형태로 호출되었기 때문에 this가 지정되지 않아서 출력된 this는 전역객체가 됩니다.

호출 주체가 없다고 판단될 때, 자동으로 전역객체를 바라보게 되는데, 이를 막고(바인딩하지 않고) 호출 당시 주변 환경의 this를 그대로 상속 받도록 하는 방법은 다음과 같습니다.

  1. 현재 컨텍스트의 this를 변수로 저장하고 내부 함수에서 사용하는 방식
    obj의 메서드로써 outer를 호출함으로 obj1객체가 this로 지정되고 결과적으로 self함수에는 obj1이 담기게 됩니다.
  var obj1 = {
    outer: function() {
      ...
      var self = this;
      var innerFunc = function() {
        console.log(self);
      }
      innerFunc();
    }
  }
  1. 화살표 함수 사용
    ES6에 도입된 화살표 함수는 애초에 함수 호출시(실행 컨텍스트 생성시) this 바인딩 과정이 빠지게 되서 상위 스코프의 this를 그대로 활용할 수 있습니다.
  var obj = {
    outer: function() {
      console.log(this);	//  obj1: {outer f}
      var innerFunction = () => {
          console.log(this); // obj1: {outer f}
      }
      innerFunction(); 	
    }
  };
  obj.outer();
  1. 콜백 함수
    콜백 함수의 경우, 명시적으로 this를 지정할 수 있습니다. 이런 형태는 여러 내부 요소에 반복적인 동작을 수행해야 하는 배열 메서드에 많이 포함되어 있습니다.

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

  1. call
    call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령입니다.
    첫번째 인자로 this를 바인딩하고, 이후에는 호출할 함수의 매개변수를 “,”로 구분해서 넣습니다. 함수를 그냥 실행하지 않고 call메서드를 통해 실행하게 되면 임의의 객체를 this로 지정해서 호출할 수 있습니다.
    var func = function(a, b, c) {
      console.log(this, a, b, c);
    }

    func(1, 2, 3);
    func.call({x: 1), 1, 2, 3);
  1. apply
    apply함수도 기능적으로 call메서드와 완전히 동일하지만, 호출할 함수에 전달할 매개변수를 배열 하나로 묶어서 두번째 인자로 전달할 수 있습니다.
  2. bind
    bind메서드의 경우, 즉시 실행하는 call과는 달리 인자로 받은 this와 매개변수로 넘겨줄 인자들을 바탕으로 새로운 함수를 반환하는 메서드입니다.
    bind메서드를 통해 this를 미리 적용할 수 있고, 호출할 함수에 넘겨줄 매개변수를 bind를 호출할 때뿐만이 아닌 반환된 새로운 함수를 호출할 때도 넘겨줄 수 있어 부분 적용 함수를 구현할 수 있습니다.
    또한, bind메서드를 적용한 함수라는 것을 알아볼 수 있도록 bind메서드를 통해 반환된 새로운 함수는 name프로퍼티에 “bound”라는 접두어가 붙습니다.
    var func = function(a, b, c, d) {
      console.log(this, a, b, c, d);
    }

    var bindFunc = func.bind({x: 1}, 4, 5);
    bindFunc(6, 7) // {x: 1}, 4 5 6 7

0개의 댓글