이번 책을 통해 알아 볼 주요한 자바스크립트의 개념
스코프, 클로저, 프로토타입, 타입과 타입 강제 변환
Javascript는 마케팅 목적으로 사람들을 속이기 위해 고안된 이름
Mocha -> LiveScript -> Javascript 순서로 이름이 변경
Java 개발자들에게 어필하는 목적 + Script가 '가벼운 프로그램'이라는 뜻으로 유행하던 상황적 배경의 결합
Javascript와 Java는 별개의 언어지만 코드가 완전히 다르지는 않음
표면상 비슷한 부분이 많이 있음
C언어와 유사한 문법을 기대하는 개발자를 대상으로 만들어졌기 때문
(블록 시작과 끝에 중괄호를 사용하는 것, 문이 끝날 때 세미콜론을 사용하는 것 등)
Javascript는 Oracle이 소유한 상표
ECMAScript는 TC39에서 지정하고 ECMA 표준 기구에 의해 공식화된 명칭
TC39는 JS를 관리하는 기술 운영 위원회 JS의 공식 명세를 관리함
TC39위원들은 정기 모임에서 명세 변경 안건 투표 진행
합의된 변경 사항을 국제 표준화 기구인 ECMA에 제출
이 명세서에 JS 문법과 작동 방식 정의
TC39 위원회는 약 50~100명으로 구성되어 있으며, 브라우저를 만드는 조직과 하드웨어 제조사 인원으로 구성
TC39에서 모든 제안은 다섯 단계로 이루어진 절차를 거침 (0단계 ~ 4단계)
누구나 명세서 관련 토론 및 제안서 작성 과정에 참여 가능
TC39 회의에서 TC39위원에 의해 의결됨
TC39와 ECMA에 의해 유지되는 공식적인 표준 JS는 단 하나
모든 주요 브라우저 제조사, 디바이스 제조사는 단 하나뿐인 명세서를 기준으로 JS 구현체를 만듦
브라우저 엔진별로 명세서 개정안 반영 시기는 다르나, 규칙을 어기는 일은 절대 없어야 함
JS는 브라우저, 서버(Node.js), 로봇, 전구 등에서 실행되며 점차 그 범위를 확장 중
이 중에서 가장 큰 비중을 차지하는 것은 웹
JS 구현체를 만들 때 웹 브라우저 환경을 최우선 고려
명세서에 정의된 JS와 브라우저 엔진에서 돌아가는 JS는 동일. 하지만 몇 가지 차이점이 있음
가끔씩 새로운 동작 추가 및 기존 작동 방식 변경 등의 명세서 개정
개정안이 기존 브라우저 엔진에서 실행되던 JS의 작동 방식과 다른 경우가 발생
JS 엔진 제조사들은 오류 없이 웹 콘텐츠를 보여주기 위해 에지 케이스를 다루는 기능을 자체적으로 추가
명세서 개정안 반영 시 기존에 잘 보이던 콘텐츠가 깨지는 경우, 자사 엔진 미반영 결정
불일치 발생 시, TC39 위원회는 종종 기존 결정 철회 후, 명세서를 웹에 맞춤
때때로 TC39가 브라우저 기반 JS엔진이 명세서를 준수할 가능성이 거의 없음에도 명세서 변경을 안 하는 경우가 있음
문제가 생길 수 있지만, ECMAScript 명세서와 실제 웹에서 돌아가는 차이가 상세히 기록된 명세서 페이지의 부록 B를 참고하여 해결 가능
부록 B에 적힌 예외들은 브라우저에서만 허용, 다른 환경은 명세서를 반드시 준수하여야 함
브라우저 엔진, Node.js 등과 같이 JS가 실행되는 환경은 전역 스코프에 API를 추가해 자체적으로 사용할 수 있는 기능을 제공
JS처럼 보이는 API 상당수가 웹에서만 지원되는 API인 경우가 많음
fetch(), getUserMedia() 등
JS에 정의된 문법이 아니지만 JS 함수와 객체 메서드 규칙을 따르고 JS처럼 보이는 것이 있음
alert(), console.log() 등
브라우저 개발자 도구 콘솔이나 Node.js의 REPL환경이 JS 환경이라는 전제하에 빠르게 JS 코드 작성과 실행을 위해 이 둘을 사용함. 하지만 이 전제는 틀린 전제임
개발자 도구는 개발자 편의를 위해 만들어져 개발자 경험을 가장 우선순위에 둠
개발자 도구는 명세서에 정의된 명세를 정확히 재현하기 위해 만든 도구가 아님
개발자 도구가 JS 프로그램 처리 방식을 항상 엄격하게 준수하지도 않고, 이를 기대해서도 안 됨
콘솔에 나타난 결과가 JS 문법을 정확히 지키더라도 결과를 신뢰해서는 안 됨
명세서를 항상 읽고, 개발자 도구는 'JS에 우호적인' 별도의 환경임을 유념
프로그래밍 언어에서 패러다임이라는 용어는 코드를 어떻게 구조화할지에 대한 접근 방식과 사고 방식을 의미
세상에는 다양한 프로그래밍 패러다임이 있고, 한 패러다임 안에는 스타일과 형식에 차이를 둔 변형이 무수히 존재 하며, 이런 형태를 라이브러리나 프레임워크의 형태로 접하게 됨
절차적, 객체지향, 함수형 패러다임 등이 대표적
절차적 패러다임
코드가 톱다운이면서 선형적 구조화
프로시저라 불리는 코드 단위에 미리 정해진 일련의 연산을 작성
객체지향 패러다임
클래스 기준으로 구조화
클래스에는 로직과 데이터가 정의 됨
함수형 패러다임
코드를 함수 단위로 구조화
함수는 부수 효과가 없는 순수 함수이며 함수 자체가 값으로 취급된다는 특징이 있음
JS는 다중 패러다임 언어
절차적, 객체지향, 함수형 모두 작성 가능
한 줄 한 줄 원하는 패러다임을 적용하는 것도 가능
JS를 지탱하는 기본 원칙 중 하나는 하위 호환성 보장
하위 호환성이란 단 한번이라도 유효한 JS 문법이라고 인정되면, 명세서가 변경되더라도 절대 그 유효성이 깨지지 않는다는 의미
하위 호환성 덕분에 오래 전에 작성한 코드가 시간이 흘러도 무조건 작동한다는 것을 보장
JS는 하위 호환성을 보장하므로 개발자는 브라우저 버전이 업데이트 되더라도 직접 작성한 코드가 깨지지 않을 것이라는 자신감을 가지고 작업 가능
하위 호환성과 대응되는 개념으로 상위 호환성이 있음
새로운 명세서에 추가 된 문법으로 코드 작성 시, 이전 명세서를 준수하는 구형 엔진에서 문제가 생기지 않는 것
JS는 상위 호환성을 보장하지 않고, 반면에 HTML, CSS는 상위 호환성 보장
개발자는 JS가 하위 호환성을 보장한다는 사실과 이점. 제약, 어려움을 함께 알고 있어야 함
JS는 상위 호환성을 보장하지 않기에 아주 오래된 엔진에서는 유효한 문법으로 작성한 코드가 돌아가지 않을 가능성이 있음
명세서에 새롭게 추가되었지만, 구 엔진과 호환되지 않는 문법은 트랜스파일을 통해 호환성 문제를 해결 가능
트랜스파일이란, 한 형태에서 다른 형태로 소스 코드를 변환해주는 것
상위 호환성으로 발생하는 문제 대부분은 트렌스파일러를 사용하면 해결 가능
트랜스파일러는 새로운 JS 문법을 오래된 문법으로 바꿔주며, 주로 바벨(Babel)을 사용
상위 호환성 문제가 새로운 문법이 아닌, 근래 추가되었지만 아직 지원하지 않는 API메서드 때문이라면, 메서드 정의를 추가하여 이 메서드가 오래된 환경에서도 있었던 것처럼 해주는 방법이 가장 일반적
이런 패턴을 폴리필(polyfill) 또는 심(Shim)이라 함
폴리필이 필요할 때는 ES-Shim과 같은 공신력 있는 폴리필을 사용하여야 함
트랜스파일이나 폴리필은 오래된 환경이나 애플리케이션과 JS 최신 기능의 간극을 메꾸는 가교 역할을 함
스크립트 언어나 인터프리터 언어는 대게 위에서 아래로 한 줄씩 코드가 실행되는 방식으로 만들어지며, 보통 실행이 시작되기 전에 거치는 사전 단계가 없음
인터프리터나 스크립트 언어로 작성한 프로그램의 특정 줄에 오류가 있다면,
해당 줄의 직전 줄이 실행되기 전까지 오류를 발견할 수 없음
프로그램이 실행되기 전에 파싱이라 부르는 사전 단계를 거치는 언어도 있음
파싱과 컴파일을 거치는 언어는 파싱 단계에서 오류를 발견하여 사전에 오류 차단 가능
파싱을 거치는 언어와 컴파일을 거치는 언어의 공통점이 있음
모든 컴파일 언어는 파싱을 거침
파싱이 끝나면 언젠가 컴파일이 진행될 것이라 예상 가능
고전 컴파일러 이론에서는 파싱 이후의 절차 중 마지막 단계에서 실행 가능한 코드의 형태가 만들어짐
파싱이 완전히 끝난 다음에는 파싱 결과인 추상 구문 트리(AST)를 컴퓨터가 실행할 수 있는 형태로 바꿔주는 작업이 이어짐
파싱을 거치는 언어는 파싱에서 끝나는 것이 아니라, 실행 가능한 코드를 생성하는 작업까지 수행
따라서 파싱을 거치는 언어는 컴파일 언어로 통용
JS로 작성한 소스 코드는 실행 전에 파싱을 거침
JS에서 파싱이 끝난 코드는 한 줄씩 처리되지 않고, 컴파일러를 거쳐 최적화된 이진 코드로 변환된 후 실행
컴파이 단계에서는 JS 가상 머신에 전달할 이진 바이트 코드가 생성
JS 엔진은 파싱 이후 생성된 코드를 다양한 방법으로 실행 전에 그때그때 처리 및 최적화
JS로 만든 코드가 실행될 때까지 거치는 절차
1) 바벨이 트랜스파일하고 웹팩을 비롯한 번들러를 거쳐 번들링되고 그 결과가 JS 엔진에 전달
2) JS 엔진은 전달 받은 코드를 파싱해 추상 구문 트리로 바꿈
3) JS 엔진은 이어서 추상 구문 트리를 이진 바이트 코드로 바꿈
(이 과정에서 JIT 컴파일러가 작동하여 최적화)
4) JS 가상 머신이 프로그램 실행
JS가 주력이 아닌 개발자도 JS 엔진에서 돌아가는 코드를 쉽게 작성할 수 있게 해주는 데 목적
일반 JS와는 완전히 다른 프로그램 형태로 제작되어 실행 전 단계인 파싱과 컴파일을 거치지 않아 파싱과 컴파일에 따른 본질적인 지연을 피한다는 특징
어셈블리 언어와 유사하며, JS 엔진에서 일어나는 일반적인 처리 프로세스와 달리 파싱, 컴파일 없이 처리
Wasm으로 만든 프로그램의 파싱 및 컴파일은 실행 직전(AOT)에 일어나고 배포는 JS 엔진의 별도 처리가 많이 필요하지 않은 바이너리 파일 형식으로 진행
엄격 모드는 '할 수 없는 것에 제약을 두는 모드'가 아님
엄격 모드는 JS 엔진이 코드를 최적화하고 효율적으로 실행할 수 있게 해주는 최고의 안내 가이드
린터같은 도구를 사용해 엄격 모드로 작업하면 비 엄격모드에서 발생할 수 있는 실수와 문제를 미연에 방지할 수 있어 협업이 수월해 짐
엄격 모드에서만 활성화되는 가이드 대부분은 초기 오류의 형태
초기 오류는 엄밀히 말해 구문 오류는 아니지만 코드 실행 전 컴파일 단계에서 잡아낼 수 있는 오류
파일 대상으로 적용되는 엄격 모드는 전처리구문 'use strict'; 가 있는 경우 활성화
이 구문 앞에는 주석이나 공백만 허용
함수 단위로도 적용 가능하며 함수에도 파일 단위 엄격 모드와 동일한 규칙이 적용
파일 단위 엄격 모드가 적용되면 함수에는 엄격모드 전처리 구문 사용 불가능
파일에만 엄격 모드를 적용하거나, 함수에만 엄격 모드를 적용해야 함
함수 단위 엄격 모드는 비 엄격모드에서 작성했던 기존 프로그램에 점진적으로 엄격 모드를 적용해야 할 때만 사용하는 것이 좋음
이런 경우가 아니라면 파일이나 프로그램 전체를 대상으로 한 번에 엄겨 모드를 적용하는 것이 더 나음
JS는 ECMA 주최하에 TC30 위원회가 결정하는 ECMAScript 표준을 구현한 언어
JS는 브라우저를 비롯한 Node.js 등의 다양한 환경에서 실행
JS는 다중 패러다임 언어
절차적, 객체 지향, 함수형 모두를 활용하여 코드를 작성할 수 있음
JS는 컴파일 처리되는 언어
JS 엔진을 비롯한 도구가 코드를 처리하고, 코드를 실행하기전에 코드를 점검하며 오류가 있으면 오류 보고