자바스크립트에서 스코프(scope)와 this
는 자주 헷갈리는 개념 중 하나다.
특히 렉시컬 스코프(lexical scope)와 this
는 동작 방식이 다르기 때문에 혼동하기 쉽다.
이번 글에서는 렉시컬 스코프와 this
의 차이를 정리하고,
this
가 어떻게 결정되는지 명확한 규칙을 정리해보겠다. 🚀
렉시컬 스코프는 "코드를 작성할 때" 스코프(변수의 유효 범위)가 결정되는 방식이다.
즉, "함수가 어디서 실행되었느냐"가 아니라, "어디서 선언되었느냐"에 따라 스코프가 결정된다.
function outer() {
let outerVar = "I'm outer!";
function inner() {
console.log(outerVar); // inner() 안에서는 outerVar를 사용할 수 있음
}
inner();
}
outer();
✅ inner()
함수는 어디서 실행되었느냐가 아니라, 어디서 "정의되었느냐"에 따라 outerVar
를 참조할 수 있다.
✅ 즉, 렉시컬 스코프는 선언된 위치를 기준으로 스코프를 결정한다.
📌 자바스크립트는 기본적으로 렉시컬 스코프를 따른다!
하지만 this
는 예외적으로 렉시컬 스코프와 다르게 동작한다.
this
는 어떻게 동작할까?this
는 변수처럼 보이지만, 함수 실행 시점에서 결정되는 특수한 키워드다.
즉, 함수가 어디에서 선언되었느냐가 아니라, 어떻게 호출되었느냐에 따라 this
가 달라진다.
this
의 결정 방식✔ 일반 함수는 단독 실행될 경우 this = window
(strict 모드에서는 undefined
).
✔ 객체의 메서드로 실행될 경우, this = 해당 객체
.
✔ 객체의 메서드를 변수에 할당하면, this
가 window
가 된다.
✔ 일반적인 콜백 함수(setTimeout
)에서 this
는 window
가 된다.
this
로 가리킨다.=>
)는 this
를 바인딩하지 않고, 상위 렉시컬 스코프에서 가져온다.new
키워드를 사용하면, this
는 새로 생성된 객체를 가리킨다. this
의 동작 방식 정리호출 방식 | this 가 가리키는 대상 |
---|---|
일반 함수 (function ) | window (strict 모드에서는 undefined ) |
객체의 메서드 (obj.method() ) | obj (해당 객체) |
메서드를 변수에 할당 (const f = obj.method ) | window (strict 모드에서는 undefined ) |
일반적인 콜백 함수 (setTimeout ) | window |
이벤트 핸들러 (addEventListener ) | 이벤트 발생 요소 |
화살표 함수 (=> ) | 상위 렉시컬 스코프의 this |
new 키워드 사용 (new Constructor() ) | 새로 생성된 객체 |
this
예제 코드this
function sayHello() {
console.log(this);
}
sayHello(); // ❌ window (strict 모드에서는 undefined)
this
const obj = {
name: "Joonc",
sayHello: function () {
console.log(this.name);
}
};
obj.sayHello(); // ✅ "Joonc" (this는 obj)
const greet = obj.sayHello;
greet(); // ❌ undefined (this는 window)
this
function sayHello() {
console.log(this);
}
setTimeout(sayHello, 1000); // ❌ window (일반 함수 호출)
this
const btn = document.querySelector("button");
btn.addEventListener("click", function () {
console.log(this); // ✅ 버튼 요소 (이벤트 발생 요소)
});
this
const obj = {
name: "Joonc",
sayHello: () => {
console.log(this.name);
}
};
obj.sayHello(); // ❌ undefined (this는 obj가 아닌 window)
✅ 일반 함수(function
)에서는 this
가 obj
를 가리키지만,
✅ 화살표 함수(=>
)에서는 this
가 obj
가 아니라, 상위 스코프(전역 객체)를 가리킨다!
new
키워드를 사용한 경우function Person(name) {
this.name = name;
}
const me = new Person("Joonc");
console.log(me.name); // ✅ "Joonc" (this는 me)
✅ new
를 사용하면 새로운 객체가 생성되면서 this
가 해당 객체를 가리킴.
✔ 자바스크립트의 스코프는 렉시컬 스코프를 따른다.
✔ 하지만 this
는 렉시컬 스코프처럼 동작하지 않고, "어떻게 호출되었느냐"에 따라 결정된다.
✔ 객체의 메서드로 실행되면 this
는 객체를 가리킨다.
✔ 콜백 함수로 전달되면 기본적으로 전역 객체를 가리킨다.
✔ 이벤트 핸들러의 경우 this
는 자동으로 이벤트가 발생한 요소를 가리킨다.
✔ 화살표 함수는 this
를 바인딩하지 않고, 상위 렉시컬 스코프의 this
를 따른다.
✔ new
키워드를 사용하면 this
는 새로 생성된 객체를 가리킨다.
자바스크립트에서 렉시컬 스코프와 this
는 다르게 동작한다는 점을 이해하는 것이 핵심이다.
렉시컬 스코프는 "선언된 위치"를 기준으로 결정되지만,
this
는 "함수 호출 방식"에 따라 결정된다.