this와 스코프(Scope)의 동작 방식

joon·2025년 2월 17일
0

자바스크립트에서 스코프(scope)this는 자주 헷갈리는 개념 중 하나다.
특히 렉시컬 스코프(lexical scope)this는 동작 방식이 다르기 때문에 혼동하기 쉽다.
이번 글에서는 렉시컬 스코프와 this의 차이를 정리하고,
this가 어떻게 결정되는지 명확한 규칙을 정리해보겠다. 🚀


📌 1️⃣ 렉시컬 스코프(Lexical Scope)란?

렉시컬 스코프는 "코드를 작성할 때" 스코프(변수의 유효 범위)가 결정되는 방식이다.
즉, "함수가 어디서 실행되었느냐"가 아니라, "어디서 선언되었느냐"에 따라 스코프가 결정된다.

✅ 렉시컬 스코프 예제

function outer() {
    let outerVar = "I'm outer!";
    
    function inner() {
        console.log(outerVar); // inner() 안에서는 outerVar를 사용할 수 있음
    }

    inner();
}

outer();

inner() 함수는 어디서 실행되었느냐가 아니라, 어디서 "정의되었느냐"에 따라 outerVar를 참조할 수 있다.
✅ 즉, 렉시컬 스코프는 선언된 위치를 기준으로 스코프를 결정한다.

📌 자바스크립트는 기본적으로 렉시컬 스코프를 따른다!
하지만 this는 예외적으로 렉시컬 스코프와 다르게 동작한다.


📌 2️⃣ this는 어떻게 동작할까?

this변수처럼 보이지만, 함수 실행 시점에서 결정되는 특수한 키워드다.
즉, 함수가 어디에서 선언되었느냐가 아니라, 어떻게 호출되었느냐에 따라 this가 달라진다.

📌 this의 결정 방식

✔ 일반 함수는 단독 실행될 경우 this = window (strict 모드에서는 undefined).
✔ 객체의 메서드로 실행될 경우, this = 해당 객체.
✔ 객체의 메서드를 변수에 할당하면, thiswindow가 된다.
✔ 일반적인 콜백 함수(setTimeout)에서 thiswindow가 된다.

  • 단, 이벤트 핸들러로 쓰이는 콜백 함수는 이벤트가 호출된 요소를 this로 가리킨다.
    ✔ 화살표 함수(=>)는 this를 바인딩하지 않고, 상위 렉시컬 스코프에서 가져온다.
    new 키워드를 사용하면, this새로 생성된 객체를 가리킨다.

📌 3️⃣ this의 동작 방식 정리

호출 방식this가 가리키는 대상
일반 함수 (function)window (strict 모드에서는 undefined)
객체의 메서드 (obj.method())obj (해당 객체)
메서드를 변수에 할당 (const f = obj.method)window (strict 모드에서는 undefined)
일반적인 콜백 함수 (setTimeout)window
이벤트 핸들러 (addEventListener)이벤트 발생 요소
화살표 함수 (=>)상위 렉시컬 스코프의 this
new 키워드 사용 (new Constructor())새로 생성된 객체

📌 4️⃣ this 예제 코드

1. 일반 함수에서 this

function sayHello() {
    console.log(this);
}
sayHello();  // ❌ window (strict 모드에서는 undefined)

2. 객체의 메서드에서 this

const obj = {
    name: "Joonc",
    sayHello: function () {
        console.log(this.name);
    }
};

obj.sayHello();  // ✅ "Joonc" (this는 obj)

3. 객체의 메서드를 변수에 할당한 경우

const greet = obj.sayHello;
greet();  // ❌ undefined (this는 window)

4. 콜백 함수에서 this

function sayHello() {
    console.log(this);
}

setTimeout(sayHello, 1000);  // ❌ window (일반 함수 호출)

5. 이벤트 핸들러에서 this

const btn = document.querySelector("button");
btn.addEventListener("click", function () {
    console.log(this);  // ✅ 버튼 요소 (이벤트 발생 요소)
});

6. 화살표 함수에서 this

const obj = {
    name: "Joonc",
    sayHello: () => {
        console.log(this.name);
    }
};
obj.sayHello();  // ❌ undefined (this는 obj가 아닌 window)

일반 함수(function)에서는 thisobj를 가리키지만,
화살표 함수(=>)에서는 thisobj가 아니라, 상위 스코프(전역 객체)를 가리킨다!

7. new 키워드를 사용한 경우

function Person(name) {
    this.name = name;
}

const me = new Person("Joonc");
console.log(me.name);  // ✅ "Joonc" (this는 me)

new를 사용하면 새로운 객체가 생성되면서 this가 해당 객체를 가리킴.


📌 5️⃣ 최종 정리

✔ 자바스크립트의 스코프는 렉시컬 스코프를 따른다.
✔ 하지만 this는 렉시컬 스코프처럼 동작하지 않고, "어떻게 호출되었느냐"에 따라 결정된다.
✔ 객체의 메서드로 실행되면 this는 객체를 가리킨다.
✔ 콜백 함수로 전달되면 기본적으로 전역 객체를 가리킨다.
✔ 이벤트 핸들러의 경우 this는 자동으로 이벤트가 발생한 요소를 가리킨다.
✔ 화살표 함수는 this를 바인딩하지 않고, 상위 렉시컬 스코프의 this를 따른다.
new 키워드를 사용하면 this새로 생성된 객체를 가리킨다.


🚀 마무리

자바스크립트에서 렉시컬 스코프와 this는 다르게 동작한다는 점을 이해하는 것이 핵심이다.
렉시컬 스코프는 "선언된 위치"를 기준으로 결정되지만,
this는 "함수 호출 방식"에 따라 결정된다.

0개의 댓글