How to Read the ECMAScript Specification (1: 서론)

Woody·2022년 2월 28일
0
post-thumbnail

이 글은 How to Read the ECMAScript Specification(Timothy Gu)을 번역한 것입니다. 원문은 다음 링크에서 찾아보실 수 있습니다. 번역이 완벽하지 않을 수 있습니다. 혹시 잘못된 부분이 있다면 댓글이나 이메일로 알려주세요!

분량이 많아 부분별로 나눠서 올릴 예정입니다 :) 이번 글은 1장 Prelude에 해당하는 부분입니다.


Abstract

ECMAScript Language specification(aka. JavaScript 스펙 또는 ECMA-262)는 JavaScript가 어떻게 동작하는지 공부할 수 있는 좋은 자료입니다. 하지만 양이 어마어마하기 때문에 처음에는 혼란스럽거나 겁먹을 수 있죠. 이 문서는 최고의 JavaScript 레퍼런스를 읽기 시작하는 것을 쉽게 만드는 것을 목표로 하고 있습니다.

1. 서론

ECMAScript 스펙을 매일 조금씩 읽는 것은 여러분들의 건강에 좋습니다. 새해의 목표 때문이던, 의사의 처방 때문이던 탁월한 선택입니다!

이 문서에서는 스펙 자체를 부르기 위해서는 오로지 "ECMAScript”라는 용어만 사용하고 다른 모든 곳에서는 "JavaScript”를 사용합니다. 하지만 두 단어 모두 같은 것을 지칭합니다. (역사적인 이유로 ECMAScript와 JavaScript에는 차이가 있지만 이건 문서의 범위를 벗어나므로 Google that distinction에서 찾아보세요)

1.1 왜 우리는 ECMAScript 스펙을 읽어야 하는가

ECMAScript는 모든 JavaScript 구현의 동작에 대한 권위적인 자료입니다. 여러분들의 브라우저[WHATISMYBROWSER], Node.js를 이용한 서버[NODEJS], 혹은 IoT 디바이스 등[JOHNNY-FIVE]에 상관 없이 말이죠. 모든 JavaScript 엔진 개발자들은 멋지고 새로운 기능을 개발하기 위해 이 스펙에 의존할 수밖에 없습니다.

하지만 이 스펙의 유용성이 “JavaScript 엔진 개발자”로 알려진 신화 속의 존재에게만 유용하다고 생각하지 않습니다. 그걸 넘어서 여러분들과 같은 보통의 JavaScript 코더들에게도 유용하죠. 단지 여러분들은 그걸 깨닫지 못했을 뿐입니다.

어느 날 일을 하다가 다음과 같이 이상한 코드를 발견했다 해봅시다:

> Array.prototype.push(42)
1
> Array.prototype
[ 42 ]
> Array.isArray(Array.prototype)
true
> Set.prototype.add(42)
TypeError: Method Set.prototype.add called on incompatible receiver #<Set> at Set.add (<anonymous>)
> Set.prototype
Set {}

왜 어떤 메소드는 프로토타입에 작동하고 다른 메소드들은 이 프로토타입에 작동하지 않는지 헷갈리게 되죠. 불행하게도 구글은 가장 필요할 때 항상 실패하고 없이는 못사는 스택오버플로우도 마찬가지입니다.

이 때 스펙을 읽는 것은 도움이 될 수 있습니다.

또는 도대체 왜 악명높은 loose equality operator(==)가 제 기능을 하는지 궁금할 수도 있습니다.(여기서 “기능”은 대충 쓰여진 단어입니다 [WAT]). 공부하기 좋아하는 개발자들은 MDN에서 몇 문단에 달하는 설명을 볼 수 있지만 눈만 아플 뿐입니다 [MDN].

이 때 스펙을 읽는 것은 도움이 될 수 있습니다.

하지만 저는 JavaScript를 막 사용하기 시작한 개발자들에게는 ECMAScript 스펙 읽기를 추천하지 않습니다. 입문자라면 웹에서 마음껏 뛰어노세요! 웹 앱을 만들어보거나 다른 사람을 놀래킬 수 있는, 혹은 그 무엇이던 만들어보세요! 그리고 JavaScript 사용에 충분히 숙련되었을 때나 JavaScript에 대해 고민하지 않아도 될 때 이 문서로 다시 돌아오는 것을 생각해보세요.

이제 스펙이 복잡한 언어나 플랫폼을 이해하는 데 도움이 된다는 것을 충분히 이해했을 것 같네요. 그런데 정확히 어떤 것들이 ECMAScript에 포함되어 있을까요?

1.2 ECMAScript에 포함된 것과 아닌 것들

교과서적인 정답은 “오로지 언어와 관련된 기능만 ECMAScript 스펙에 포함된다”입니다. 하지만 이런 건 그다지 도움이 안되죠. “JavaScript의 기능들은 JavaScript다”라고 말하는 것과 별반 다를 게 없으니까요. 그리고 저는 동어 반복을 그리 좋아하지도 않습니다.

대신 JavaScript 앱을 만들 때 흔히 보이는 것들 중 몇 개를 나열하고 각각이 언어 기능에 포함됐는지 아닌지 말해드리겠습니다.

[1] ECMAScript 스펙은 이러한 선언 문법과 무엇을 의미하는지 명시하고 있지만 모듈이 어떻게 로드되는지에 대해서는 명시하지 않고 있습니다.
[2] 이들은 브라우저나 Node.js 모두에서 사용 가능하지만 표준은 아닙니다. Node.js의 경우 자체 문서에 문서화 및 명세화되어있습니다. 브라우저의 경우 consoleConsole 표준에 명세되어있고 나머지는 HTML 표준에 명세되어 있습니다.
[3] 이들은 모두 Node.js에서만 사용 가능한 global이고 자체 문서에 문서화 및 표준화되어 있습니다.
* globalglobalThis는 다름에 주의하세요. globalThis는 ECMAScript의 일부이고 브라우저에도 구현되어 있습니다.
[4] 이들은 Node.js에서만 사용 가능한 모듈 “전역” 객체입니다. 자체 문서에 문서화 및 표준화되어 있습니다.
[5] 이들은 브라우저에서만 사용 가능합니다.

1.3 더 나아가기 전에: ECMAScript 스펙은 어디에 있나요?

구글에 “ECMAScript Specification”을 검색하면 모두 자신들이 표준이라 외치는 스펙들을 볼 수 있습니다. 어떤 걸 읽어야 할까요?

한 줄 요약: tc39.es/ecma262의 배포본이 여러분들이 찾는 스펙입니다

좀 더 긴 설명:

ECMAScript 언어 스펙은 다양한 배경을 가진 사람들이 모인 Ecma International Technical Committee 39(혹은 TC39라는 더 친숙한 이름도 있죠[TC39])라는 그룹의 사람들에 의해 개발되고 있습니다[TC39]. TC39는 tc39.es에서 최신 버전의 ECMAScript를 관리합니다[ECMA-262].

문제를 복잡하게 만드는 것은 매년 TC39는 특정 시점에 스냅샷으로 에디션 번호와 함께 해당 연도의 ECMAScript 언어 표준을 정한다는 것입니다. 예를 들어 ES10이나 ES2019로 널리 알려진 ECMAScript® 2019 Language Specification (ECMA-262, 10th edition) [ECMA-262-2019]의 경우 2019년 6월 PDF로 변환되어 영구 보존을 위해 포름알데히드에 담궈진 것입니다(역주-해부학 샘플들은 포름알데히드 용액에 보존됩니다).

그래서 2019년 6월에 포름알데히드에 담궈진 브라우저에서만 동작하는 웹 어플리케이션을 만드려는 의도가 아닌 이상 tc39.es에서 항상 최신 버전의 스펙을 참고하는 것이 좋습니다. 하지만 옛 버전의 브라우저나 Node.js를 지원하려면 옛 버전의 스펙을 찾아보는 것이 도움이 될 것입니다.

참고: ISO/IEC 또한 ECMAScript 언어 스펙을 ISO/IEC 22275로 재발행합니다. 하지만 걱정 마세요. 여전히 표준은 다음 링크에 있습니다. [ECMA-262]

1.4 스펙 살펴보기

ECMAScript는 정말 방대한 양을 다루고 있습니다. 저자들이 논리적으로 구분하기 위해 최선을 다하고 있기는 하지만 여전히 긴 텍스트입니다.

개인적으로는 스펙을 5 부분으로 나누려 합니다.

  • 컨벤션과 기본 사항들 (Number란? 스펙에서 ‘TypeError 예외를 던져라`라고 말하는 것은 무슨 의미인가?)
  • 언어의 문법 규칙 (for - in 루프는 어떻게 작성할까?)
  • 언어의 정적 의미 (변수명들은 var statement 내에서 어떻게 결정되는가?)
  • 언어의 런타임상 의미 (for - in 루프는 어떻게 실행되는가?)
  • API들 (String.prototype.substring()은 무슨 역할을 하는가?)

하지만 이 분류는 실제 스펙이 구분된 방식이 아닙니다. 첫 번째 부분은 §5 Notational Conventions부터 §9 Ordinary and Exotic Objects Behaviours까지 산재해있고 다음 세 부분은 §10 ECMAScript Language: Source Code 부터 §15 ECMAScript Language: Scripts and Modules까지 퍼져있습니다. 다음과 같이 말이죠:


  • §13.6 The if Statement 언어의 문법 규칙
  • §13.6.1-6 언어의 정적 의미
  • §13.6.7 언어의 런타임상 의미
  • §13.7 Iteration Statements 언어의 문법 규칙
    • §13.7.1 언어의 정적 의미와 런타임상 의미가 섞여 있음
    • §13.7.2 The do``while Statement
      • §13.7.2.1-5 언어의 정적 의미
      • §13.7.2.6 언어의 런타임상 의미
    • §13.7.3 The while Statement
      • ...

그리고 마지막인 API들은 §18 The Global Object 부터 §26 Reflection까지 나눠져 있습니다.

여기서 스펙을 처음부터 끝까지 읽는 사람은 아무도 없다는 사실을 말하고 싶습니다. 그보다는 대부분은 필요한 장, 그 중에서도 필요한 부분만을 읽을 것입니다. 이 때 여러분이 찾고 싶은 것이 위에서 말한 다섯 가지 분류 중 어디에 속하는지 생각해보세요. 만약 나누는 데 어려움이 있다면 스스로 질문을 해보세요. “이게(이것이 무엇이던지 간에) 계산되는 시점이 어디지?”라는 질무에 답하는 것은 도움이 될 수도 있습니다. 걱정하지 마세요. 연습 후에는 스펙을 살펴보는 것이 어렵지 않을 겁니다.

profile
코드야 내가 잘못했어

0개의 댓글