일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 티스토리챌린지
- java 애노테이션
- import 키워드
- 창의적도구
- java super메소드
- java 패키지
- ai활용법
- java 메서드 오버라이딩
- java final 키워드
- java
- asyncawait
- java반복문
- 화살표연산자
- binraytree
- java 이진트리
- javascript
- java objact클래스
- java스터디
- java_this
- js메서드
- 자바스크립트
- java 제네릭
- java 추상 클래스
- this키워드
- 생성형AI
- JAVA데이터타입
- gpt활용팁
- javatime
- 오블완
- javautil패키지
- Today
- Total
코딩쿠의 코드 연대기
JavaScript의 this: 개념부터 실전 활용 본문
JavaScript의 this 사용법과 실전 예제
this는 JavaScript에서 함수가 실행되는 **문맥(context)**을 나타내는 키워드로, 호출 방식에 따라 동적으로 값이 결정됩니다. this의 동작은 코드를 작성할 때 헷갈릴 수 있지만, 이해하면 보다 유연하고 강력한 코드를 작성할 수 있습니다. 아래에서는 다양한 상황에서의 this 사용법을 예제와 함께 살펴보겠습니다.
1. 전역 콘텍스트에서의 this
console.log(this); // 브라우저에서는 window 객체, Node.js에서는 global 객체
전역 컨텍스트에서 this는 기본적으로 글로벌 객체를 참조합니다.
2. 객체 메서드에서의 this
const obj = {
name: 'John',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
obj.greet(); // 출력: Hello, John!
- 설명: 객체의 메서드에서 this는 해당 메서드를 호출한 객체를 참조합니다. 위 예제에서 greet 메서드 내부의 this는 obj를 가리킵니다.
3. 생성자 함수에서의 this
function Person(name) {
this.name = name;
}
const john = new Person('John');
console.log(john.name); // 출력: John
- 설명: 생성자 함수에서 this는 새로 생성된 객체를 참조합니다. Person 함수는 new 키워드를 사용해 호출되었고, 이로 인해 this는 john 객체를 가리키게 됩니다.
4. 이벤트 핸들러에서의 this
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this); // 출력: 클릭된 버튼 요소
});
- 설명: 이벤트 핸들러 내부에서 this는 이벤트가 발생한 DOM 요소를 참조합니다. 위 예제에서는 클릭된 button 요소가 this가 됩니다.
5. 화살표 함수에서의 this
const obj = {
name: 'John',
greet: () => {
console.log(`Hello, ${this.name}!`);
}
};
obj.greet(); // 출력: Hello, undefined!
- 설명: 화살표 함수는 자신만의 this를 생성하지 않고 상위 스코프의 this를 상속받습니다. 따라서 위 코드에서 화살표 함수 내부의 this는 글로벌 객체를 참조합니다.
6. this 바인딩 변경
call, apply, bind 메서드를 사용하여 this를 명시적으로 변경할 수 있습니다.
const obj = { name: 'John' };
function greet() {
console.log(`Hello, ${this.name}!`);
}
greet.call(obj); // 출력: Hello, John!
greet.apply(obj); // 출력: Hello, John!
const boundGreet = greet.bind(obj);
boundGreet(); // 출력: Hello, John!
- 설명:
- call: 함수 호출과 함께 this를 설정.
- apply: call과 유사하지만, 인자를 배열로 전달.
- bind: 새로운 함수로 this를 고정.
7. 비동기 컨텍스트에서의 this
비동기 작업에서도 this는 호출 방식에 따라 달라질 수 있습니다.
const obj = {
name: 'John',
greet: function() {
setTimeout(function() {
console.log(this.name); // 출력: undefined
}, 1000);
}
};
obj.greet();
위 예제에서 setTimeout 내의 this는 글로벌 객체를 참조합니다. 이를 해결하려면 다음 중 하나를 사용할 수 있습니다.
- 해결책 1: bind 사용
setTimeout(function() {
console.log(this.name);
}.bind(this), 1000);
- 해결책 2: 화살표 함수 사용
setTimeout(() => {
console.log(this.name);
}, 1000);
예제와의 연관성: 실전 코드에 적용하기
1. 단순 대화 함수
function displayMessage(message, sender) {
const messageElement = document.createElement('div');
messageElement.classList.add(sender === 'ai' ? 'ai-message' : 'user-message');
messageElement.textContent = message;
chatContainer.appendChild(messageElement);
console.log(this); // `displayMessage`가 호출된 컨텍스트
}
위 코드에서 displayMessage 내부의 this는 호출하는 방식에 따라 다르게 평가됩니다.
2. Chatbot UI Integration
sendButton.addEventListener('click', function() {
console.log(this); // 버튼 요소
});
3. Using Promises and Async/Await에서의 this
비동기 작업을 수행하는 함수에서도 this의 값은 호출 컨텍스트에 따라 달라집니다. 이를 관리하지 않으면 다음과 같은 문제가 발생할 수 있습니다.
문제 상황:
const obj = {
name: 'Chatbot',
async fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
console.log(`${this.name} received:`, data.title);
} catch (error) {
console.error(this.name, 'Error:', error);
}
}
};
obj.fetchData(); // 정상적으로 실행: this는 obj를 참조
위 코드는 정상적으로 작동합니다. 그러나 this가 엉뚱한 값을 참조하게 되는 경우도 있습니다.
this 관리 문제
const obj = {
name: 'Chatbot',
async fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
console.log(`${this.name} received:`, data.title);
} catch (error) {
console.error(this.name, 'Error:', error);
}
}
};
const fetchDataFunc = obj.fetchData;
fetchDataFunc();
// TypeError: Cannot read properties of undefined (reading 'name')
- 원인: fetchData 메서드를 객체에서 분리해서 호출하면 this가 글로벌 객체 또는 undefined(strict mode)로 평가됩니다.
해결책: bind, call, 또는 apply를 활용
const boundFetchData = obj.fetchData.bind(obj);
boundFetchData(); // 정상 동작
해결책: 화살표 함수 사용 (상위 스코프의 this 유지)
const obj = {
name: 'Chatbot',
fetchData: async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
console.log(`${this.name} received:`, data.title);
} catch (error) {
console.error(this.name, 'Error:', error);
}
}
};
obj.fetchData(); // 출력: undefined received: (제대로 동작하지 않음!)
주의: 화살표 함수는 상위 스코프의 this를 상속하기 때문에, 객체의 메서드로 사용할 경우 의도한 this를 참조하지 않을 수 있습니다. 이 방법은 적합하지 않습니다.
가장 권장되는 방법: 메서드 형태 유지
객체 메서드로 호출되도록 설계하면 불필요한 this 관련 문제를 피할 수 있습니다.
obj.fetchData(); // 안전하고 명확하게 동작
요약:
- 비동기 함수에서도 this를 정확히 이해해야 의도한 결과를 얻을 수 있습니다.
- this가 문제를 일으킬 가능성이 있다면 bind를 사용해 명시적으로 바인딩하거나 객체 메서드로 호출하는 방식을 고수하세요.
비동기 함수에서도 this의 값을 정확히 이해하고 관리해야 코드를 예측 가능하게 작성할 수 있습니다.
'코딩스터디 > JavaScript' 카테고리의 다른 글
JS) 코딩 테스트에서 자주 사용되는 메서드 (0) | 2024.12.31 |
---|---|
TypeScript) Interface 이해하기 (0) | 2024.11.27 |
JS) for...in과 for...of의 차이와 올바른 사용 방법 (0) | 2024.11.25 |
JS)비동기 처리란 무엇인가? 콜백부터 콜백 지옥 해결까지 (0) | 2024.11.24 |