본문 바로가기

TOPIC

JavaScript 모든 this의 바인딩 상황

반응형

프론트 엔드를 공부를 시작하면서 this에 관련된 상황에 대해서 어떻게든 사용하고 있었지만 그것은 감으로 사용하고 있었고 정확하게 이렇게 될거야라는 확신은 없는채 사용해 왔다. 이렇게 사용하면 되겠지.. 하지만 특수한 경우에는 생각되로 바인딩 되지 않는 경우가 있는데 그러한 경우를 모아서 정리해볼려고 한다.

 

JavaScript에서는 this는 상황에 따라 다른 표현을 가지고 있다. 상황에 따른 this가 어디로 할당 되는지 다루어 볼려고 한다.

기본 적으로 this는 함수내에서 암묵적으로 전달되는 변수이다.

 

1. 객체의 메소드를 호출할 때

var Obj = {
    name: 'this',
    func: function() {
        console.log(this);
    }
};

Obj.func();
// { name: 'this', func: [Function: func] }

객체의 프로퍼티가 함수일 경우 그 안의 this는 호출한 객체를 대상으로 한다. (함수를 소유하고 있는)

function함수의 this는 호출한 Obj가 대상이므로 Obj를 호출한다.

 

2. 함수를 호출 할 때

var name = 'global_this';

var Obj = {
    name: 'this',
    func1: function() {
        console.log("this is "+ this);

        var func2 = function() {
            console.log("this is " + this);
        };

        func2();
    }
};
Obj.func1();
// this is [object Object]
// this is [object global]

func1 내부는 첫번 째 경우로 호출한 객체의 대상인 Obj로 바인딩 된다. 하지만 func2의 this는 객체의 파라미터의 함수가 아니라 함수로 정의되어 있다. 이런 경우는 글러벌 this로 바인딩 된다. 

 

3. new키워드를 통한 생성.

var Test = function(a) {
    console.log(this);
    this.a = a;
    this.func = function() {
        console.log(this.a);
    }
};

var test = new Test("AAA");
console.log(test.a);
test.func();
// Test {}
// AAA
// AAA

new 키워드로 생성한 객체내에서 this는 객체 그자체가 된다.  따라서 생성자에 의해서 호출되는 this는 빈 this가 된다.

그후 객체내의 함수가 호출 하는 this는 상황1의 상황처럼 호출한 객체의 this를 바인딩하게 되므로 Test가 된다.

 

4. bind 메소드 활용

var Obj = {
    name: 'innerThis',
    func1: function() {
        console.log(this);

        var func2 = function() {
            console.log(this);
        }.bind(this);
        func2();
    }
};

Obj.func1();
// { name: 'innerThis', func1: [Function: func1] }
// { name: 'innerThis', func1: [Function: func1] }

bind를 활용해서 현재 this를 다음 함수의 this로 전달한다. 실제로 func2의 내부 this는 글로벌 this를 가르켜야하지만 bind로 인해서 같은 Obj의 객체를 가리키게 된다.

 

5. call 메소드 활용

var Obj = {
    name: 'innerThis',
    func1: function() {
        console.log(this);

        var func2 = function() {
            console.log(this);
        };
        func2.call(this);
    }
};

Obj.func1();
// { name: 'innerThis', func1: [Function: func1] }
// { name: 'innerThis', func1: [Function: func1] }

 

6. apply 메소드 활용

var Obj = {
    name: 'innerThis',
    func1: function() {
        console.log(this);

        var func2 = function() {
            console.log(this);
        };
        func2.apply(this);
    }
};

Obj.func1();
// { name: 'innerThis', func1: [Function: func1] }
// { name: 'innerThis', func1: [Function: func1] }

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

 

Function.prototype.bind() - JavaScript | MDN

bind() 메소드가 호출되면 새로운 함수를 생성합니다. 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공됩니다.

developer.mozilla.org

7. Promisse (콜백 함수 대신 사용하는 최근 유행)

8. async await (내부 구현부 Promisse)

9. 화살표 함수 this

function Person(){
    this.age = 0;
  
    setInterval(() => {
      this.age++; // |this|는 person 객체를 참조
      console.log(this.age);
    }, 1000);
  }
  
  var p = new Person();

일반 함수에서 this는 자기자신을 표현하지만 화살표함수는 this, arguments, super를 바인딩 하지 않는다.

그렇다면 this는 어디서 가져올가?? 자기보다 높은 단계에 있는 상위 스코프에서 가져오게 된다. 따라서 this.age로 접근이 가능하다.

반응형

'TOPIC' 카테고리의 다른 글

SVG  (0) 2021.07.29
접근성 : ARIA-TAB  (0) 2021.07.21
[프로그래머스] 고양이 사진 검색 사이트  (2) 2021.07.08
mac 구매후 설치방법(개발자용)  (0) 2021.06.08
JOIN 안에 SUB쿼리를 JOIN으로 바꿔보자  (1) 2021.01.17