You don't know JS - this (1)

박춘화·2021년 9월 8일
0

You don't know JS

목록 보기
2/4
post-thumbnail

What is 'this'? 🤔

함수에서 사용되는 'this'는 참 어려운 개념이다. 필자의 경우 파이썬으로 프로그래밍을 입문했는데, 자바스크립트의 'this'가 파이썬 클래스 내부에서 인스턴스를 가리키는 'self'와 유사했기 때문에 'this'도 해당 스코프를 가지는 함수를 가리키는 것으로 이해했었다.
You don't know JS에서도 많은 개발자들이 함수에서의 'this'를 다음과 같이 이해하고 있다고 한다.

  • 함수
  • 함수의 스코프

결론부터 말하자면 둘 다 잘못 이해한 것이다. 그 이유에 대해 하나씩 살펴보도록 하자.

'this' !== 함수

자바스크립트에 정의된 거의 모든 것들은 객체(Object)이며, 함수 역시 객체다. 그러므로 함수 또한 객체처럼 참조하여 상태(state)를 저장할 수 있을거라 생각하기 쉽다. 다음 코드를 보자.

function foo() {
    this.callCount += 1
}

foo.callCount = 0

console.log(Object.keys(foo)) // ['callCount']
foo()
console.log(foo.callCount) // 0

Object.keys()를 이용하여 확인한 결과 foocallCount 키를 가진다는 것이 확인됐다. 하지만 foo를 호출하여 callCount를 증가시켰지만 반영이 안된 것으로 보아 foo 블록 내부의 'this'는 foo를 가리키지 않는다. foo 블록 내부에서 'this'를 출력하면 다음과 같이 나온다.

function foo() {
  console.log(this) // <ref *1> Object [global] { ...
}
foo()

그렇다. 'this'는 Node.js의 전역 객체인 global를 가리키고 있다. 처음 코드를 다음과 같이 변경해보자.

function foo() {
    this.callCount += 1
}

global.callCount = 0 // 절대로 이렇게 쓰시면 안됩니다!

foo()

console.log(global.callCount) // 1

정상적으로 값이 증가했다! 그러므로 'this' 항상 전역 객체인 global을 가리킨다...라고 결론을 내리기에는 성급한 감이 있다. 왜냐하면 우리는 분명 'this'가 자기 자신을 가리키는 경우를 한번 쯤은 경험해봤기 때문이다.

'this' !== 함수의 스코프

'this'가 함수를 가리키는 것이 아니니까 함수의 스코프를 가리킨다는 주장은 충분히 일리가 있는 말처럼 들린다. You don't know JS에서는 이 부분을 설명하기 위해 다음과 같은 예제 코드를 활용했다.

function foo() {
    var a = 2
    bar()
}

function bar() {
    console.log( this.a ) // undefined
}

foo()

함수의 스코프는 함수의 선언과 함께 생성된다. barfoo 내부에서 호출되었는데, 만약 'this'가 함수 bar의 스코프를 가리킨다면 스코프 체인에 의해 bar 내부에서 'this'를 사용하여 foo의 변수 a에 접근할 수 있어야한다.
하지만 출력 결과가 undefined이므로 'this'는 함수의 스코프를 가리키는 것이 아니게 된다.

그럼 'this'는 대체 뭔데? 😥

MDN 웹 문서에서는 'this'를 다음과 같이 설명한다.

자바스크립트에서 함수의 this는 다른 언어와 조금 다르게 동작한다. 대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정된다. 실행 중에는 할당으로 설정할 수 없고, 호출할 때마다 다를 수 있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

여기서 우리가 주목할 문장은 "함수를 호출하는 방법에 의해 결정된다."이다. 이 문장을 통해 'this'는 항상 동일한 대상을 가리키지 않고 'this'를 가지는 함수를 호출하는 방법에 따라 서로 다른 대상을 가리킨다는 사실을 알 수 있다.

You don't know JS - this (2)로 이어집니다.

profile
함께 성장하는 개발자

0개의 댓글