자바스크립트 this 키워드 완전 정리: 개념부터 실무 예제까지
완전 정리! 자바스크립트 this 키워드 가이드
자바스크립트에서 this 키워드는 정말 헷갈리면서도 중요한 개념이에요.
저도 처음 자바스크립트를 공부할 때는 "아니 도대체 이게 왜 이렇게 동작하지?" 하면서 머리를 쥐어뜯은 기억이 있어요 😅
하지만 차근차근 원리를 이해하고 다양한 예제를 접하다 보면, this
는 오히려 자바스크립트를 더 자유롭고 강력하게 만들어주는 도구라는 걸 깨닫게 돼요.
이번 글에서는 this의 기본 개념 → 실행 컨텍스트 → 전역/함수/메서드/클래스/화살표 함수 → call/apply/bind → 이벤트/타이머 → 실무 사례(React, Vue, Node.js) → FAQ 까지 아주 풍부하게 다뤄볼 거예요.
📌 this 키워드란 무엇인가요?
한 줄 정의: this
는 함수가 호출될 때 결정되는 실행 컨텍스트의 참조 값이에요.
많은 언어에서 this
는 "현재 객체"를 가리킨다고 설명하지만, 자바스크립트는 다릅니다.
자바스크립트에서는 함수가 어떻게 호출되었는지(call site) 에 따라 this
가 달라져요.
이게 헷갈림의 핵심이에요.
📌 실행 컨텍스트와 this
자바스크립트 코드는 실행될 때 실행 컨텍스트(Execution Context) 라는 환경 안에서 동작해요.
각 실행 컨텍스트에는 다음 정보가 들어있어요:
- 변수 환경 (Variable Environment)
- 렉시컬 환경 (Lexical Environment)
- this 바인딩
👉 즉, this의 값은 실행 컨텍스트가 생성될 때 결정돼요.
이제 각각의 상황에서 어떻게 달라지는지 살펴봅시다!
📌 전역 컨텍스트에서의 this
// 브라우저
console.log(this) // window
// Node.js
console.log(this) // {}
- 브라우저: 전역 객체
window
- Node.js: 모듈 시스템 때문에 빈 객체
{}
👉 이미 여기서부터 혼란이 시작돼요. 같은 코드라도 환경에 따라 다르게 동작하거든요.
📌 일반 함수 호출에서의 this
function showThis() {
console.log(this)
}
showThis()
- 엄격 모드가 아닐 때:
window
(브라우저 전역 객체) - 엄격 모드(
'use strict'
)일 때:undefined
'use strict'
function strictModeTest() {
console.log(this)
}
strictModeTest() // undefined
👉 즉, 엄격 모드 여부에 따라 this 값이 확 달라져요.
📌 객체 메서드 호출에서의 this
const user = {
name: '철수',
greet() {
console.log(`안녕하세요, 저는 ${this.name}이에요!`)
}
}
user.greet() // 안녕하세요, 저는 철수이에요!
👉 여기서는 this
가 user
객체를 가리켜요.
즉, 메서드를 소유한 객체가 this가 된다는 규칙이 적용돼요.
❌ 자주 하는 실수
const hello = user.greet
hello() // 엄격 모드: undefined / 비엄격 모드: window
👉 이렇게 메서드를 변수에 담아 호출하면 this가 깨져요!
✅ 해결: bind
사용
const helloBound = user.greet.bind(user)
helloBound() // 안녕하세요, 저는 철수이에요!
📌 중첩 객체에서의 this
const team = {
name: '개발팀',
member: {
name: '영희',
introduce() {
console.log(`저는 ${this.name}이에요!`)
}
}
}
team.member.introduce() // 저는 영희이에요!
👉 여기서 this는 member
객체를 가리켜요.
즉, 점(.) 앞에 오는 객체가 누구인지에 따라 결정돼요.
📌 생성자 함수와 클래스에서의 this
생성자 함수
function Person(name) {
this.name = name
}
const p1 = new Person('민수')
console.log(p1.name) // 민수
👉 new
를 사용하면 새로운 객체가 만들어지고, 그 객체가 this가 돼요.
클래스
class Car {
constructor(model) {
this.model = model
}
show() {
console.log(`이 차는 ${this.model}이에요!`)
}
}
const c = new Car('Tesla')
c.show() // 이 차는 Tesla이에요!
📌 화살표 함수에서의 this
화살표 함수는 자신만의 this를 가지지 않고, 상위 스코프의 this를 그대로 사용해요.
const obj = {
name: '홍길동',
say: () => {
console.log(this.name)
}
}
obj.say() // undefined
👉 여기서 this는 obj가 아니라 전역(window)을 참조해요.
올바른 활용 예시
function Timer() {
this.seconds = 0
setInterval(() => {
this.seconds++
console.log(this.seconds)
}, 1000)
}
new Timer()
👉 화살표 함수 덕분에 setInterval 안에서도 바깥 this(Timer 인스턴스)를 사용할 수 있어요.
📌 call, apply, bind로 this 바꾸기
function introduce(age) {
console.log(`${this.name}, ${age}살이에요.`)
}
introduce.call({ name: '지영' }, 25) // 지영, 25살이에요.
introduce.apply({ name: '민호' }, [30]) // 민호, 30살이에요.
const boundFunc = introduce.bind({ name: '수지' }, 28)
boundFunc() // 수지, 28살이에요.
👉 정리:
- call → 즉시 실행, 인자 리스트 전달
- apply → 즉시 실행, 인자 배열 전달
- bind → 새 함수 반환
📌 이벤트 핸들러에서의 this
<button id="btn">Click</button>
<script>
document.getElementById('btn').addEventListener('click', function() {
console.log(this) // 버튼 요소
})
</script>
👉 여기서 this는 이벤트가 걸린 요소를 가리켜요.
⚠️ 하지만 화살표 함수를 쓰면 달라져요:
document.getElementById('btn').addEventListener('click', () => {
console.log(this) // window
})
📌 setTimeout / setInterval에서의 this
setTimeout(function() {
console.log(this) // window
}, 1000)
👉 해결: 화살표 함수 사용
setTimeout(() => {
console.log(this) // 상위 스코프의 this
}, 1000)
📌 React에서의 this
클래스 컴포넌트
class Counter extends React.Component {
constructor(props) {
super(props)
this.state = { count: 0 }
this.increment = this.increment.bind(this)
}
increment() {
this.setState({ count: this.state.count + 1 })
}
render() {
return <button onClick={this.increment}>클릭 {this.state.count}</button>
}
}
👉 bind
를 해주지 않으면 this
가 undefined가 돼요.
👉 함수형 컴포넌트에서는 화살표 함수 + hooks로 해결돼요.
📌 Vue에서의 this
new Vue({
data() {
return { msg: 'Hello' }
},
methods: {
show() {
console.log(this.msg)
}
}
})
👉 Vue 2에서는 this가 컴포넌트 인스턴스를 가리켜요.
👉 Vue 3 Composition API에서는 this
대신 setup()
반환값을 사용하죠.
📌 Node.js에서의 this
console.log(this) // {}
function normal() {
console.log(this)
}
normal() // undefined (strict mode)
👉 Node.js는 모듈 시스템 때문에 전역 this가 다르게 동작해요.
📌 this가 헷갈리는 대표적인 20가지 예제
- 전역 함수 호출
- 엄격 모드 함수 호출
- 객체 메서드 호출
- 메서드 분리 후 호출
- 중첩 객체
- 생성자 함수
- 클래스
- 클래스 메서드 분리
- 화살표 함수
- 화살표 함수 + setTimeout
- call
- apply
- bind
- 이벤트 핸들러 (일반 함수)
- 이벤트 핸들러 (화살표 함수)
- setInterval 안 this
- React 클래스 컴포넌트
- React 함수형 컴포넌트 (hook 활용)
- Vue 2 Options API
- Node.js 모듈 스코프
👉 각 상황을 직접 실행해보면서 익히면 머리에 쏙 들어와요!
❓ FAQ: this 관련 자주 묻는 질문
- 자바스크립트에서 this는 무엇인가요?
- 엄격 모드에서 함수 호출 시 this는 왜 undefined인가요?
- 화살표 함수의 this는 어떻게 결정되나요?
- 객체 메서드를 분리해서 호출하면 왜 this가 깨지나요?
- call, apply, bind 차이는 뭔가요?
- 이벤트 핸들러에서 this는 무엇을 가리키나요?
- setTimeout 안 this는 왜 window인가요?
- React 클래스 컴포넌트에서 this 바인딩은 왜 필요한가요?
- Vue 3에서는 this를 왜 쓰지 않나요?
- Node.js에서 전역 this는 왜 {} 인가요?
📚 참고 자료
✅ 마무리
자바스크립트의 this
는 호출 방식에 따라 달라지는 동적 키워드예요.
헷갈리지만, 다양한 예제와 실무 사례를 경험하다 보면 자연스럽게 익숙해질 거예요.
👉 이제는 this
가 더 이상 무섭지 않죠? 🚀