Home [잔뿌리 호기심] 일반함수의 this는 왜 전역객체가 바인딩될까?
Post
Cancel

[잔뿌리 호기심] 일반함수의 this는 왜 전역객체가 바인딩될까?

[잔뿌리 호기심]은 잔뿌리처럼 메인 주제에서 뻗어 나온 개인적인 궁금증을 다룹니다.

여러 가지 this 바인딩

우리는 Chapter 22 - this👨‍💻 에서 여러 가지 this의 바인딩에 대해서 알아봤다.
그 과정에서 나는 책을 바탕으로 글을 작성하다 보니, 책에는 나와 있지 않은 두 가지 가벼운 궁금증이 생겼다.

  1. 일반 함수에서는 왜 전역 객체(window) 가 바인딩 될까?
  2. 나머지 4가지 경우의 this 바인딩은 어떻게 이루어질까?

총 2개의 글을 통해 위 두 가지 주제에 대해서 알아볼까 한다.
이번 주제는 ‘일반 함수에서는 왜 전역 객체(window) 가 바인딩 될까?’ 이다.

일반함수의 this 바인딩과 전역 객체

먼저 this의 필요성을 다시 정리하고 넘어가자.
this는 객체의 메서드가 속해있는 객체의 프로퍼티에 접근하기 위한 접근자 키워드이다. 따라서 나에겐 일반함수의 경우엔 this가 있어야 할 이유가 명확하지 않다고 비춰졌다.

하지만 실제로 일반 함수에 this를 호출해 보면 전역 객체인 window 가 바인딩 되는 것을 확인할 수 있다. Javascript의 유연한 구조를 조금이나마 강제하는 ‘use strict’ 키워드를 사용하면 undefined 가 바인딩 된다.

나 또한 일반함수에서의 this는 undefined 가 바인딩 되어야 하는 것이 이치상 맞다고 생각되는데,

  1. Javascript는 ‘어떤 기준’으로 해당 함수가 일반 함수인 줄 알고 전역 객체를 바인딩 하는 것일까?
  2. ‘왜 하필 전역 객체’를 바인딩하는 것일까?

이 두 가지 질문에 대해서 다뤄보도록 하겠다.

Javascript의 바인딩 알고리즘

먼저 ‘어떤 기준’ 에 대해서 얘기해 보고자 한다.

먼저 해당 함수가 어떤 함수로 호출 되었는지. 메서드인지, 일반 함수인지, 생성자 함수인지 판별하는 알고리즘은 ECMAScript 사양에 의해 결정되고 문서화 된다.

ECMAScript-2023 🌎

조금 ‘더 깊이’ 알아보고 싶다면, 위 ECMAScript 문서에서 ‘Function Calls’ 섹션과 ‘This Keyword’ 섹션을 참조하면 좋다.

필자도 실제로 ECMAScript 문서를 들여다본 것은 처음인데 상당히 보기 좋게 작성되어 있다.
순서를 함수 단위로 나누어서,
해당 함수를 따라가기만 하더라도 그 프로세스를 이해하기가 명확하고 쉬웠다. 이게 클래스 차이일까…?

정리하자면, ‘어떤 기준’ 에 해당하는 해당 바인딩 알고리즘은 ECMAScript에 의해 결정되며, Javascript엔진(V8) 에 저장되어 브라우저 단에서 확인하는 것이라고 생각하면 될 것 같다.

왜 하필 전역 객체일까?

책에서도 확인할 수 있듯이, Node.js 환경에서는 즉시 undefined 가 바인딩 되는 것을 알 수 있다.
하지만 왜 기본적으로는 전역 객체가 바인딩되는 것일까?

이것에 대한 이유는 역사적인 이유가 섞여 있었다.

초기 Javascript 에서는 모든 메서드와 프로퍼티는 window 객체에 속해있었기 때문에 그 당시 일반함수의 this가 window 객체를 가리키는 것은 당연한 이치였다.
시간이 지나고 더 이상 모든 메서드와 프로퍼티가 window 객체에 속해있지 않게 되었지만, this 바인딩을 변경하기엔 수많은 기존 서비스에 영향을 미칠 수 있기에 보류되었고 그것이 현재까지 이어지게 되었다.

이를 부분적으로나마 해결하기 위해 나온 기능이 바로 strict 모드이다.
( 보통 strict 모드로 고쳐지는 건 JS 개발자도 실수라고 인정하는 부분 같더라 )
일반 함수에서 ‘use strict’와 함께 this 를 사용하면 undefined 가 바인딩 되는 것을 확인해 볼 수 있다.

결론

  • 일반 함수 호출은 항상 전역 객체에 바인딩 된다.
  • 이 기준은 ECMAScript 사양에 의해 결정되어 Browser Javascript 엔진에 저장되어 적용된다.
  • 전역 객체 바인딩의 이유는 초기 Javascript 의 특성에 의해 결정된 전역 객체 바인딩이 레거시 코드들의 안정성을 위해 유지되다가 변경되지 못했다.

다음 주제의 글은 잔뿌리 호기심 - 다른 4가지 경우에서의 this 바인딩 여기서 확인할 수 있다.

This post is licensed under CC BY 4.0 by the author.

CORS란 무엇일까? ... with SOP

[잔뿌리 호기심] 다른 4가지 경우에서의 this바인딩