반응형
1. 기본적인 this 동작 방식
this는 함수가 호출되는 방식에 따라 값이 달라집니다. 주요한 패턴은 다음과 같습니다.
1.1 전역 컨텍스트에서의 this
console.log(this); // 브라우저에서는 Window 객체, Node.js에서는 global 객체
전역에서 this를 출력하면 브라우저 환경에서는 window 객체를, Node.js 환경에서는 global 객체를 참조합니다.
1.2 일반 함수에서의 this (엄격 모드와 일반 모드)
function showThis() {
console.log(this);
}
showThis(); // 브라우저에서는 window, Node.js에서는 global
"use strict";
function strictShowThis() {
console.log(this);
}
strictShowThis(); // undefined (엄격 모드에서는 `this`가 undefined)
- 일반 모드: this는 전역 객체(window 또는 global)를 참조합니다.
- 엄격 모드("use strict"): this는 undefined가 됩니다.
1.3 객체의 메서드에서의 this
const obj = {
name: "Alice",
showThis: function () {
console.log(this.name);
}
};
obj.showThis(); // "Alice"
- 메서드를 호출한 객체(obj)가 this가 됩니다.
하지만 함수 내부에서 새로운 함수가 호출되면 this가 바뀔 수 있습니다.
const obj = {
name: "Alice",
showThis: function () {
function inner() {
console.log(this);
}
inner(); // 일반 함수로 호출되므로 `this`는 `window` 또는 `undefined`(엄격 모드)
}
};
obj.showThis();
- 해결 방법:
- self 또는 that 변수를 활용 (var self = this;)
- .bind(this) 사용
- 화살표 함수 사용 (아래에서 설명)
2. 생성자 함수와 this
function Person(name) {
this.name = name;
}
const p1 = new Person("Alice");
console.log(p1.name); // "Alice"
- new 키워드를 사용하여 생성자 함수를 호출하면 this는 새로 생성된 객체를 참조합니다.
만약 new 없이 호출하면 this가 전역 객체를 가리키거나(비엄격 모드) undefined(엄격 모드)로 설정됩니다.
const p2 = Person("Bob"); // new 없이 호출
console.log(p2); // undefined
console.log(global.name); // "Bob" (Node.js의 경우)
해결 방법:
- new 없이 호출될 경우 this가 올바른 객체를 참조하도록 강제하는 패턴 사용
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
3. 화살표 함수에서의 this
화살표 함수는 일반 함수와 다르게 this를 바인딩하지 않고, 자신을 포함하는 외부 스코프(렉시컬 스코프)의 this를 사용합니다.
const obj = {
name: "Alice",
showThis: function () {
const arrow = () => {
console.log(this.name);
};
arrow();
}
};
obj.showThis(); // "Alice"
- arrow 함수는 obj.showThis()의 this를 유지합니다.
하지만 화살표 함수는 생성자 함수로 사용할 수 없습니다.
const Person = (name) => {
this.name = name;
};
const p = new Person("Alice"); // TypeError: Person is not a constructor
4. bind, call, apply를 이용한 this 변경
4.1 call()과 apply()
call()과 apply()를 사용하면 특정한 this를 설정하여 함수를 실행할 수 있습니다.
function showName() {
console.log(this.name);
}
const user = { name: "Alice" };
showName.call(user); // "Alice"
showName.apply(user); // "Alice"
- call(thisArg, arg1, arg2, ...) → 개별 인자로 전달
- apply(thisArg, [arg1, arg2, ...]) → 배열로 전달
4.2 bind()
bind()는 새로운 함수를 반환하여 이후에 this가 고정된 상태로 실행되도록 합니다.
function showName() {
console.log(this.name);
}
const user = { name: "Alice" };
const boundFn = showName.bind(user);
boundFn(); // "Alice"
- bind()를 사용하면 this가 영구적으로 고정됩니다.
5. 이벤트 핸들러에서의 this
5.1 일반 함수에서의 this
const button = document.querySelector("button");
button.addEventListener("click", function () {
console.log(this); // 클릭된 button 요소를 참조
});
5.2 화살표 함수에서의 this
button.addEventListener("click", () => {
console.log(this); // window 객체를 참조
});
- 화살표 함수는 이벤트 핸들러로 사용될 때 this가 window가 되어 문제가 발생할 수 있습니다.
해결 방법:
- bind(this)를 사용하거나, 일반 함수 표현식을 사용
6. 클래스에서의 this
클래스 메서드에서는 this가 자동으로 인스턴스를 가리킵니다.
class Person {
constructor(name) {
this.name = name;
}
showName() {
console.log(this.name);
}
}
const p = new Person("Alice");
p.showName(); // "Alice"
하지만, 클래스 내부에서 setTimeout 등을 사용할 경우 this가 바뀔 수 있습니다.
class Timer {
start() {
setTimeout(function () {
console.log(this); // window 또는 undefined
}, 1000);
}
}
const t = new Timer();
t.start();
- 해결 방법: bind(this) 또는 화살표 함수 사용
class Timer {
start() {
setTimeout(() => {
console.log(this); // Timer 객체 유지
}, 1000);
}
}
7. 정리
호출 방식this 값
전역 실행 (일반 모드) | window (브라우저) / global (Node.js) |
전역 실행 (엄격 모드) | undefined |
객체의 메서드 | 해당 객체 |
화살표 함수 | 외부 this를 따름 (렉시컬 this) |
생성자 함수 | 새로 생성된 객체 (new 사용 시) |
call / apply | 명시적으로 지정된 객체 |
bind | 영구적으로 고정된 this |
DOM 이벤트 핸들러 (일반 함수) | 이벤트가 발생한 요소 |
DOM 이벤트 핸들러 (화살표 함수) | window |
this는 문맥에 따라 다르게 동작하므로, 실행 방식과 함수 선언 형태를 잘 이해해야 합니다.
특히 클래스 사용시에 전달값을 함수로해서 this를 사용하는 경우에 바인등을 주의깊게 살피지 않으시면 뜬금없이 에러가 발생하므로 주의깊게 사용하셔야 이상한 동작을 할 경우가 줄어듭니다.
반응형
'프로그래밍 월드 > Javascript & jQuery' 카테고리의 다른 글
[Javascript] 자바스크립트의 filter에 대하여 알아보자. (0) | 2025.03.14 |
---|---|
[Javascript] 자바스크립트의 data-속성에 대하여 알아봅시다. (1) | 2025.02.14 |
JWT(JSON Web Token)란? 서버사이드 aspx일 경우의 예제입니다. (0) | 2025.02.05 |
javascript의 class에 대하여 대략전인 시스템을 알아봅니다. (1) | 2025.01.28 |
javascript의 export import에 대하여 알아봅시다. (1) | 2025.01.27 |