자바스크립트에서 this는 구분이 느슨한 함수와 객체(메서드)를 구분하는 거의 유일한 기능
this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정
상황별 this
전역 공간
: 전역 공간에서 this는 전역 객체를 가리킴
: 브라우저 환경에서 전역 객체는 window, Node.js 환경에서는 global
메서드 내부
: this에는 호출한 주체에 대한 정보가 담김
: 호출 주체는 함수명(프로퍼티명) 앞의 객체
함수 내부
: this가 지정되지 않음
=> 실행 컨텍스트를 활성화할 당시에 this가 지정되지 않은 경우 this는 전역 객체를 바라봄
=> this는 전역 객체를 가리킴
화살표 함수
: this를 바인딩하지 않음
=> 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 되어, 상위 스코프의 this를 그대로 활용할 수 있음
=> 함수 내부에서 this가 전역 객체를 바라보는 문제를 보완하고자 ES6에서 도입
콜백 함수
: 기본적으로 함수이기 때문에 this가 전역 객체를 참조하지만, 제어권을 받은 함수에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조
생성자 함수 내부
: 어떤 함수가 생성자 함수로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신
// 전역 공간
var a = 1;
console.log(a, window.a, this.a) // 1 1 1
// 함수
var func = function (x) {
console.log(this, x);
};
func(1); // Window {...}
// 메서드
var obj = {
methodA: function () { console.log(this); },
inner: {
methodB: function () { console.log(this); }
}
};
obj.methodA(); // { methodA: f, inner: {...} } (=== obj)
obj.inner.method(); // { methodB: f } (===obj.inner)
// 화살표 함수
var obj2 = {
outer: function () {
console.log(this); // { outer: f }
var innerFunc = () => {
console.log(this); // { outer: f }
};
innerFunc();
}
};
obj.outer();
// 콜백 함수
setTimeout(function () { console.log(this); }, 300); // Window {...}
document.body.innerHTML = "<button id='a'>클릭</button>";
document.body.querySelector('#a')
.addEventListener('click', function (e) {
console.log(this, e); // <button id='a'>클릭</button>
});
// 생성자 함수
var Cat = function (name, age) {
this.bark = '야옹';
this.name = name;
};
var choco = new Cat('초코');
console.log(choco); // Cat { bark: '야옹', name: '초코' }
Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])
// ex)
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
Function.prototype.apply(thisArg[, argsArray])
// ex)
var func = function (a, b, c) {
console.log(this, a, b, c);
}
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6
Function.prototype.apply(thisArg[, arg1[, arg2[, ...]]])
// ex)
var func = function (a, b, c) {
console.log(this, a, b, c);
}
func(1, 2, 3); // Window{...} 1 2 3
var bindFunc1 = func.bind({ x: 1 });
bindFunc1(4, 5, 6); // 4 5 6