
자바스크립트에서 스코프(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 예제 코드thisfunction sayHello() {
console.log(this);
}
sayHello(); // ❌ window (strict 모드에서는 undefined)
thisconst obj = {
name: "Joonc",
sayHello: function () {
console.log(this.name);
}
};
obj.sayHello(); // ✅ "Joonc" (this는 obj)
const greet = obj.sayHello;
greet(); // ❌ undefined (this는 window)
thisfunction sayHello() {
console.log(this);
}
setTimeout(sayHello, 1000); // ❌ window (일반 함수 호출)
thisconst btn = document.querySelector("button");
btn.addEventListener("click", function () {
console.log(this); // ✅ 버튼 요소 (이벤트 발생 요소)
});
thisconst 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는 "함수 호출 방식"에 따라 결정된다.