1.2 자바스크립트 이름의 유래
- 자바스크립트는 마케팅 차원에서 지어진 이름으로, 당시 자바 개발자들에게 어필하기 위한 목적으로 “가벼운 프로그램”이라는 뜻으로 유행한 “스크립트”라는 단어를 합쳐 만들어짐
1.3 명세서
- TC39 : JS를 관리하는 기술 운영 위원회로 JS의 공식 명세를 관리함
- TC39는 정기적인 회의를 통해 명세 변경사항을 합의하고 ECMA에 제출한다
- TC39의 제안은 5단계로 나뉘며, 누군가가 새로운 명세를 제안하면 TC39 위원 중 한명이 이를 0단계에 올리면서 시작된다
- JS에는 버전이 없고, 표준 JS는 단 하나이다. 다만 브라우저 엔진별로 명세서 개정안을 반영하는 시기가 다를뿐, 규칙을 어겨서는 안된다.
JS를 지배하는 웹
- JS가 가장 많이 사용되는 분야는 웹이다
- 명세서가 개정되지만 이 개정안이 기존 브라우저 엔진에서 실행되던 JS의 작동방식과 다른 경우가 발생하기도 한다.
- JS 엔진 제조사들이 오류없이 웹 콘텐츠를 보여주기위해 에지 케이스를 다루는 기능을 자체적으로 추가하였고, 브라우저 제조사들은 새로운 개정안이 엔진과 맞지 않을 경우 새로운 개정안을 반영하지 않는 경우가 있기 떄문이다
- 이러한 상황이 발생하면 TC39 위원회는 종종 기존 결정을 취소하고 새로운 명세서를 작성하여 웹에 맞춘다(ex :
contains()
->includes()
,flatten()
->flat()
). 하지만 기존 결정을 유지하는 경우도 있다. - 이러한 문제로 인해 실제 ECMAScript 명세서와 웹에서 돌아가는 JS 사이에 차이가 존재하는 경우가 있는데, 이는 이책의 부록 B에 실려있다
- 웹에서는 쓰이지만 명세서에는 등재되지 않는 JS, 모든 엔진에서 실행되지만 결과는 다른 문법 등
JS지만 JS는 아닌 웹 전용 문법
alert()
, console.log()
, fetch()
등은 명세서에 등재된 문법이 아니라 웹 또는 엔진에서 자체적으로 추가한 API 이다.
모든 코드가 JS 인 것은 아니다
개발자 도구의 콘솔이나 Node.js의 REPL 은 JS 환경이라는 가정하에 사용되지만, JS의 프로그램 처리 방식을 항상 엄격하게 준수하지는 않는다.
- 여러 줄을 입력할때 호이스팅 작동 방식
- “전역 스코프” 최상위 레벨에서 let, const로 변수 여러 개를 선언했을 때 작동 방식
따라서 콘솔에 나타난 결과가 JS 문법을 지키더라도 결과를 신뢰하진 마라. 자세한 내용은 명세를 읽고, 개발자 도구는 JS에 우호적인 별도의 환경이라고 이해하라.
1.4 JS의 다양한 얼굴
프로그래밍에서 패러다임이란 코드를 어떻게 구조화할지에 대한 접근 방식과 사고방식을 의미한다. 하나의 패러다임에는 여러 스타일이나 형식이 있고 이는 프레임워크, 라이브러리로 나타난다.
JS는 다중 패러다임언어로 절차적, 객체지향, 함수형 스타일 코드 모두를 작성할 수 있다. 심지어 한 프로그램 안에서 여러 패러다임을 사용할 수 있다
1.5 하위 호환성과 상위 호환성
JS는 하위 호환성을 보장한다.
하위 호환성은 한 번이라도 유효한 JS 문법으로 인정되면 명세서가 변경되더라도 절대 그 유효성이 깨지지않는 것을 의미한다. 따라서 1995년에 작성된 JS 코드는 현재도 무조건 작동하는 것을 보장받는다. 따라서 JS 개발자들은 브라우저 버전이 업데이트 되어도 자신의 코드가 동작한다고 믿을 수 있다
하지만 하휘 호환성을 깨는 결정을 할때가 있는데, 이때는 브라우저로 수집한 정보를 바탕으로 하위 호환성을 깼을때 발생할 부수 효과를 판단하고, 그 근거로 투표를 통해 결정한다.
상위호환성은 구형 엔진에서 새로운 명세서를 대응하는 것을 의미하며, JS는 상위 호환성은 보장하지 않는다. 하지만 이러한 상위 호환성을 갖추려는 노력은 지속되어, 바벨 등 트랜스파일러를 통해 과거 문법으로 변환하는 식으로 대응하거나 폴리필을 사용한다.
이러한 트랜스파일러, 폴리필의 사용으로 개발자는 최신 문법을 사용한 클린한 코드를 짜는데 집중하고, 상위 호환성은 도구에 맡길 수 있다.
1.6 인터프리터 이해하기
인터프리터나 스크립트 언어로 작성된 프로그램은 위에서 한줄씩 코드가 실행되는 방식으로 만들어지며, 코드 실행 전에 거치는 단계가 없다. 또한 만약 다섯번째 줄에 에러가 있다면 네번째 줄을 실행할 때까지는 에러를 발견 못하고, 다섯번째 줄을 실행할 때 에러가 발생한다.
반면에 컴파일 언어는 실행 전 파싱, 컴파일 단계를 거치며 이 단계에서 오류를 발견할 수 있다. 일반적으로 파싱을 거치는 언어는 컴파일 단계까지 수행 후 실행 가능한 파일을 생성한다.
JS는 어떨까?
- JS는 실행 전에 파싱을 거친다. 명세서에서는 중복 매개변수 등 정적으로 탐지 가능한 초기 오류를 프로그램 실행 전에 찾아야한다고 작성되어있고, 실제로 파싱을 실행하여 이러한 오류를 잡는다.
- 또한 컴파일도 거치는데, 파싱이 완료되면 JS는 최적화된 이진 코드로 변형되어 JS VM에서 실행된다.
- JS 엔진은 심지어 파싱 이후 생성된 코드를 다양한 방법으로 실행 전에 그때그때(JIT) 처리 및 최적화한다.
정리하면 JS는
- 개발자가 작성한 코드를 바벨이 트랜스 파일하고, 번들링된 후 JS 엔진에 전달된다.
- JS 엔진은 코드를 파싱해 추상 구문 트리(AST)로 바꾼다
- 이후 AST를 이진 바이트 코드로 바꾼다. 이 과정에서 JIT 컴파일러가 작동한다.
- JS VM이 프로그램을 실행한다.
이러한 과정을 거치기에 저자는 JS가 컴파일 언어로 생각한다. 따라서 개발자가 이상한 문법을 입력하는 등 실수가 있더라도 코드 실행 전에 미리 발견할 수 있다는 특징이 있다.
웹 어셈블리
- ASM.js : JS의 부분집합으로, 일반적인 JS 코드와 스타일과 달리 일관성있는 타입 시스템을 사용하기에 성능 최적화가 매우 뛰어남. C 등의 언어로 작성한 코드를 트랜스파일한 것이므로 생성 과정에서 타입 관련 주석이 자동으로 붙는다.
- WASM (웹어셈블리) : JS가 주력이 아닌 개발자도 JS 엔진에서 돌아가는 코드를 쉽게 작성할 수 있게 해주는데 목적이 있고 이는 ASM.js 철학과 비슷하지만, ASM.js와 달리 파싱 및 컴파일 과정이 필요없다
- 성능 향상을 위해 만들어졌으며, JS가 아닌 언어로 만들어진 프로그램을 웹에서 실행시키고자 하는 움직임도 있다.
- 요즘은 웹하고는 직접적 연관이 없고, 프로그램을 컴파일 한 후 다양한 환경에서 실행할 수 있는 크로스플랫폼 가상 머신으로 발전하고 있다
1.7 엄격모드
ES5에서 추가된 메커니즘으로 파일 또는 함수의 시작부분에 "use strict";
를 작성하여 표시할 수 있다.
엄격모드는 비엄격모드에서 발생할 실수를 초기 오류의 형태로 미연에 찾아주는 등 이득이 크다, 하위호환성과 기존 코드에 기반한 관성때문에 아직 선택 사항으로 남아있다.