자바스크립트에서 this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다. 실행 컨텍스트는 함수를 호출할 때 생성되므로, this는 함수를 호출할 때 결정된다.
전역 공간에서의 this는 전역 객체(브라우저 환경에서는 window, Node.js 환경에서는 global)를 가리킨다.
메서드 내부에서의 this는 호출한 주체에 대한 정보, 즉 함수명 앞의 객체를 가리킨다.
함수에서의 this는 전역 객체를 가리킨다.
var obj1 = {
outer: function () {
console.log(this); // 1
var innerFunc = function () {
console.log(this); // 2 , 3
};
innerFunc();
var obj2 = {
innerMethod: innerFunc,
};
obj2.innerMethod();
},
};
obj1.outer();
// 1: obj1, 2: 전역객체, 3: obj2.innerMethod
this가 전역객체를 바라보는 문제를 해결하려면 this를 바인딩하지 않는 화살표 함수를 사용하자. 화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 되어, 상위 스코프의 this를 그대로 활용할 수 있다.
콜백 함수의 제어권을 가지는 함수가 콜백 함수에서의 this를 무엇으로 할지를 결정하며, 특별히 정의하지 않은 경우에는 기본적으로 함수와 마찬가지로 전역객체를 바라본다.
생성자 함수로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신이 된다.
✔️ 명시적으로 this를 바인딩하는 방법
call 메서드 : 첫 번째 인자를 this로 바인딩, 이후의 인자들은 호출할 함수의 매개변수로 지정
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func(1, 2, 3); // Window{ ... } 1 2 3
func.call({ x: 1 }, 4, 5, 6); // { x: 1 } 4 5 6
apply 메서드 : 두 번째 인자를 배열로 받아 호출할 함수의 매개변수로 지정
var func = function (a, b, c) {
console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
👉 call / apply를 이용하여 유사배열객체에 배열 메서드를 적용할 수 있다.
var obj = {
0: "a",
1: "b",
length: 2,
};
Array.prototype.push.call(obj, "c");
console.log(obj); // {0: 'a', 1: 'b', 2: 'c', length: 3}
bind 메서드 : call과 비슷하지만 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 하는 메서드
var func = function (a, b) {
console.log(this, a, b);
};
func(1, 2); // Window{ ... } 1 2
var bindFunc1 = func.bind({ x: 1 });
bindFunc1(5, 6); // { x: 1 } 5 6
❗ 화살표 함수는 함수 내부에 this가 아예 없으며, 접근하고자 하면 스코프체인상 가장 가까운 this에 접근하게 된다.