JavaScript

9. 자바스크립트에서 일반 함수의 this는 왜 window일까?

문정훈 2022. 2. 10. 02:14

1. 일반 함수에서 this는 window에 바인딩 된다. 

자바스크립트를 하면서 항상 이해가 안된던 내용이 함수 선언문으로 작성된 함수의 this는 왜 window에 바인딩이 되는 것인가??

 

자바스크립트 Depp Dive 교재에는 콜백함수이건 중첩함수이건 생성자 함수로 사용되지 않는 일반 함수의 this는 window에 바인딩된다. 라고 나와있다. 

그것이 왜 그런지에 대한 설명은 없으며 마치 정의를 내리듯이 설명하고있다. 

아래 예시 코드를 보면 

 

 

2. 예시 코드1

count = 100;
const countObj = {
  count: 1,
  addCount () {
    this.count++
    console.log('Counter Value > ', this.count)

    const addCount2 = function () {
      this.count++
      console.log('Counter Value 2 > ', this.count)
    }

    addCount2()
  }
}

countObj.addCount();

 

위 코드의 실행 결과는 2와 3이 나올것으로 기대했지만 2와 101이 나오게 된다. 

메소드는 클래스, 객체 리터럴 등에서 사용되며 메소드 내부에서 this는 객체 리터럴, 클래스 등의 객체를 바인딩한다. 

따라서 addCount는 메소드 이므로 정상적으로 2를 출력하지만 메소드 내부의 함수 선언문은 

함수 내부의 this이므로 window에 this가 바인딩된다. 

이 처럼 함수 내부의 this는 항상 window를 바인딩하는 것은 자바스크립트의 결함중 하나라고 볼 수 있으며 

많은 개발자들을 멘붕 하게 한 문제이기도 하다.

 

 

3. 화살표 함수에서 this는 어떻게 동작하나?

일반 함수에서는 [[ThisValue]] 내부 슬롯(this가 저장되는 곳) 이 있다.

하지만 화살표 함수는 이 내부 슬롯이 존재하지 않는다.

따라서 화살표 함수에서 this를 호출하는 것은 화살표 함수의 상위 스코프의 this를 찾게 된다. 

count = 100;
const countObj = {
  count: 1,
  addCount () {
    this.count++
    console.log('Counter Value > ', this.count)

    const addCount2 =()=> {
      this.count++
      console.log('Counter Value 2 > ', this.count)
    }

    addCount2()
  }
}

countObj.addCount();

메소드 내부의 함수 선언문을 화살표 함수로 변경해보았다. 위 결과를 통해 다시 정리해보면

화살표 함수에서 this 호출은 애초에 화살표 함수는 this가 없기에 자신의 상위 스코프인 addCount 메소드에서 this를 찾는다.

addCount 메소드에서 this는 객체 리터럴에 바인딩 되어있으므로 

위와 같은 결과가 나올 수 있다.