자바스크립트 this
자바스크립트 핵심 개념· 6 / 9
현재 실행 중인 함수 또는 메서드가 소속된 객체를 참조하는 키워드다.
- 실행 컨텍스트가 생성될 때 결정된다.(= 함수를 호출할 때 결정된다.)
- 함수 호출 방식에 따라 참조하는 값이 달라진다.(= 호출한 주체에 대한 정보가 담긴다.)
- this에 담기는 값은 주로 객체이다.
전역 this
전역 공간에서의 this는 전역 객체를 가리키는데, 런타임 환경에 따라 명칭과 내용이 다르다.
-
브라우저 환경 ⇒
windowconsole.log(this === window) // true -
Node.js 환경 ⇒
globalconsole.log(this === global) // true// TypeScript에서 this를 전역 객체로 가리키기 (function(this: typeof globalThis) { console.log(this === global); // true }).call(global);
호출 방식에 따라 다른 this
함수(또는 메서드) 내부에 있는 this는 그 함수(또는 메서드)가 어떤 방식으로 호출되었는지에 따라 가리키는 객체가 다르게 보인다.
-
함수로서 호출하는 경우 ⇒ 전역 객체(
windoworglobal)var func = function () { console.log(this); } func(); // window | global ⇒ 전역 객체 -
메서드로서 호출하는 경우 ⇒ 메서드를 호출한 객체
var obj = { func: function () { console.log(this); } } obj.func(); // { func: f } ⇒ 호출한 객체 obj
위 예시로 보아, 함수 호출할 때와 메서드로서 호출할 때 this가 다르게 담기는 것 같아 보이지만 함수로 호출하는 것 역시 전역 객체의 메서드로서 호출하는 것과 같기 때문에, 함수로서 호출하든 메서드로서 호출하든 this는 해당 함수(또는 메서드)를 호출한 주체(객체)를 가리킨다고 하는 것이 옳다.
특정 객체의 내부에서 선언된 함수와 메서드의 this
전역이 아닌 특정 객체 내부에서 선언된 함수라고 할지라도 함수로서 호출할 경우 내부의 this는 전역 객체를 가리킨다.
예시)
var obj = {
outer: function () {
console.log(this); // (1)
var innerFunc = function () {
console.log(this); // (2) (3)
}
innerFunc();
var obj2 = {
inner: innerFunc
};
obj2.inner();
}
}
obj.outer();
// (1): { outer: f }
// (2): window | global
// (3): { inner: f }함수로서 호출할 때 내부의 this가 해당 객체를 가리키게 하는 방법
객체 내부에서 선언된 함수라고 할지라도 함수로서 호출할 경우 내부의 this가 전역 객체를 가리키는데, 이 this가 전역 객체가 아닌 해당 객체를 가리키게 하는 방법이 있다.
-
변수 할당을 이용한 우회
var obj = { outer: function () { var self = this; var innerFunc = function () { console.log(self); // { outer: f } } innerFunc(); } } obj.outer(); -
애로우 함수(ES6)
var obj = { outer: function () { var innerFunc = () => { console.log(this); // { outer: f } } innerFunc(); } } obj.outer();
일반 함수는 실행 컨텍스트(함수 호출의 경우 전역 컨텍스트)에 따라 동적으로 this를 바인딩하지만, 애로우 함수는 정적으로 상위 스코프의 this를 그대로 참조한다.
그 외 함수에서의 this
콜백 함수와 생성자 함수에서 this가 어떻게 결정되는지 정리한다.
-
콜백 함수 내부의 this는 기본적으로 전역 객체를 가리키지만,
바인딩 메서드나배열 메서드의 thisArg 매개변수를 이용해 해당 this를 가리키도록 지정할 수 있다.// 바인딩 메서드 func.call(thisArg, arg1, arg2, ...); func.apply(thisArg, [argsArray]); const boundFunc = func.bind(thisArg);// 배열 메서드 const numbers = [1, 2, 3]; const thisArg = { value: 42, }; numbers.forEach(function(num) { console.log(num + this.value); }, thisArg); const mappedNumbers = numbers.map(function(num) { return num + this.value; }, thisArg); const filteredNumbers = numbers.filter(function(num) { return num > this.value; }, thisArg); -
생성자 함수 내부의 this는 new 연산자로 생성된 인스턴스를 가리킨다.
function Person(name, age) { this.name = name; this.age = age; } const angari = new Person('Angari', 30); console.log(angari); // Person { name: 'Angari', age: 30 }