1. 상황에 따라 달라지는 this

- 전역 공간에서의 this

console.log(this);
console.log(window);
console.log(this === window);

전역공간에서의 this = 전역객체(window)
(전역 컨텍스트를 생생하는 주체가 전역 객체이기 때문에)

var a = 1;
window.b = 2;
console.log(a, window.a, this.a);    // 1 1 1
console.log(b, window.b, this.b);    // 2 2 2 

전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다.

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

✔ 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다.

var func = function (x) {
  console.log(this, x);
}

func(1);         // window { ... } 1  
var obj = {  
method: func  
};  
obj.method(2);  // { method : f } 2

함수와 메서드로 호출하는 것은 함수 앞에 점(.) 또는 대괄호['']가 있는 것으로 구분한다. 앞에 명시된 객체 그 자체로 this가 된다.

- 함수 내부에서의 this

함수로서 호출할 경우에는 this가 지정되지 않는다. 호출 주체를 명시하지 않았기 때문이다. 그러므로 this는 전역객체를 가리킨다.

- 화살표 함수에서의 this

함수 내부에서 this가 전역객체를 바라보는 문제를 보완하고자, ES6의 화살표 함수에서는 this를 바인딩하지 않도록 설계하였다.
상위 스코프의 this를 그대로 활용할 수 있게 된다.

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

✔ 생성자 함수 : 어떤 공통된 성질을 지니는 객체들을 생성하는 데 사용하는 함수
✔ 생성자 = 클래스(class)
✔ 인스턴스 = 클래스를 통해 만든 객체

var Human = function (name, age) {
this.name = name; this.age = age;
};
var 철수 = new Human('철수', 20);
var 영희 = new Human('영희', 20);


new 명령어와 함께 생성자 함수를 호출하여 변수 '철수'와 '영희'에 할당을 하였다. 그 결과 Human 클래스의 인스턴스 객체가 담겨 출력되었다. 즉, 생성자 함수 내부에서의 this는 생성자 함수에 의해 생성된 인스턴스를 가리킨다.

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

- call 메서드

Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])

✔ 호출 주체인 함수를 즉시 실행하도록 하는 메서드
✔ 첫번째 인자를 this로 바인딩
✔ 이후 인자들을 호출할 함수의 매개변수로 지정

var obj = {
    a: 1,
    method: function (x, y) {
        console.log(this.a, x, y);
    }
};

// 점(.) 앞을 가리키는 것이 this가 된다 => obj = { ... }
// 그러므로 this.a는 1이된다.
obj.method(2, 3);                    // 1 2 3

// call 메서드로 { a: 4 }를 this로 바인딩하였다.  
// 그러므로 this.a는 4가 된다.
obj.method.call({ a: 4 }), 5, 6);    // 4 5 6

- apply 메서드

Function.prototype.apply(thisArg[, argsArray])

✔ call과 기능적으로 동일
✔ 차이점 : 두번째 인자를 배열로 받아 호출할 함수의 매개변수로 지정

var obj = {
    a: 1,
    method: function (x, y) {
        console.log(this.a, x, y);
    }
};

obj.method.apply({ a: 4 }), [5, 6])    // 4 5 6

- bind 메서드

Function.prototype.apply(thisArg[, arg1[, arg2[, ...]]])

✔ 즉시 호출하지 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하는 메서드

// { x: 1 }를 this로 바인딩하여 bindFunc1에 func을 반환한다.
var func = function (a, b, c, d) {
    console.log(this, a, b, c, d)
};

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

// { x: 1 }를 this로 바인딩하고 4와 5를 인수로 넘긴다.
// 인수로 받은 4와 5와 함께 bindFunc2에서 매개변수로 받은 6과 7이 함께 넘겨진 것처럼 동작한다.
var bindFunc2 = func.bind({ x: 1 }, 4, 5);
bindFunc2(6, 7);                                // { x: 1 } 4 5 6 7
bindFunc2(8, 9);                                // { x: 1 } 4 5 8 9

✔ 메서드의 내부 함수에서 this를 전달하기

// 내부 함수에 this를 바인딩한다.
var obj = {
    outer: function() {
        console.log(this)
        var innerFunc = function() {
            console.log(this);
        }.bind(this);
        innerFunc();
    }
};
obj.outer();
// 화살표 함수에서는 바인딩하는 과정이 제외가 되었으므로 스코프체인상 가장 가까운 this에 접근하게 된다.
var obj = {
    outer: function() {
        console.log(this)
        var innerFunc = () => {
            console.log(this);
        };
        innerFunc();
    }
};




🔖 참고

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN