3장의 this를 공부하고 다음의 질문에 답해보자.
this는 실행 컨텍스트가 생성될 때 결정됩니다. 즉, 함수를 호출할 때 생성됩니다.
전역 공간에서의 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의 값을 정확히 할 수 있습니다.
var obj1 = {
outer: function() {
console.log(this);
var innerFunc = function() {
console.log(this);
}
innerFunc(); // (2)
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod(); // (3)
}
};
obj1.outer(); // (1)
위 예제에서 함수 실행 순서에 따라 this를 추측해보면
obj1.outer()
를 실행하면 outer()
함수를 obj1
의 메서드로서 호출하고 있으므로 this는 obj1
이 됩니다.innerFunc()
함수는 함수로서 호출되고 있으므로 this는 전역 객체인 window
입니다.obj2.innerMethod()
는 innerFunc
함수를 obj2
의 메서드로 호출하고 있으므로, 이때의 this는 obj2
입니다.화살표 함수에서의 this
화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 되어, 상위 스코프의 this를 그대로 활용합니다.
이는 콜백 함수를 넘겨받아 소유권이 있는 함수 내부 로직에서 정한 규칙에 따라 값이 결정됩니다. 기본적으로 this가 전역 객체를 참조하지만 제어권을 받은 함수에서 콜백 함수에 별도로 this가 될 대상을 지정할 경우 그 대상을 참조합니다.
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function(e) {
console.log(this, e);
});
addEventListener
메서드는 콜백 함수를 호출할 때 자신의 this를 상속하도록 정의되어 있으므로 메서드명의 점(.) 앞부분이 this가 됩니다.
어떤 함수가 생성자 함수로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신이 됩니다.
이들은 명시적으로 this를 별도의 대상으로 바인딩할때 사용하는 메서드입니다.
call 메서드
call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하며, 임의의 객체를 this로 지정합니다. 이후의 인자들은 호출할 함수의 매개변수로 합니다.
apply 메서드
call 메서드와 기능적으로 완전히 동일하며, 호출할 함수의 매개변수를 전달할 때 배열로 받아 전달합니다.
bind 메서드
call과 비슷하지만 즉시 호출하지 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 합니다. 즉, bind 메서드는 함수에 this를 미리 적용하는 것과 부분 적용 함수를 구현하는 두가지 목적이 있습니다.
다음의 블로그에 있는 this 글을 보고 문제를 풀어보자.