Get started
Javascript라는 네이밍은 마케팅을 위한 결과물
공식 이름은 ECMAScript
TC39와 ECMA가 표준으로 지정
TC39 협회는 웹과 관련된 다양한 회사(브라우저, 디바이스 등)의 직원들로 구성
JS 표준은 웹에서 구현되는 것만 관여한다
모든 것이 JS는 아니다
alert()
, getCurrentLocation()
등은 JS가 아닌 JS처럼 생긴 Web API
fs.write()
등은 Node.js의 빌트인 모듈에서 나오는 api 메소드
console.log()
역시 꽤 많은 환경에서 지원하는 메소드일 뿐!
항상 JS 환경은 아니다
브라우저의 Dev tool(REPL - Read Evaluate Print Loop, console)은 실제 JS 환경이 아니다!
해결법에 대한 오해가 생길 수 있다
툴에 따라 다르다
예시
- 콘솔 최상위 레벨에
var
또는function
을 선언하는 것은 실제로 글로벌 변수를 생성하는지 - 글로벌에서
let
이나const
를 여러번 생성하면 어떻게 되는지 use strict
이 전체 세션에 영향을 미치는지this
디폴트 바인딩이 함수를 호출할 때 어떻게 동작하는지,global object
를 사용하였는지가 예상한 글로벌 변수를 포함할지- 여러 줄 사이에 호이스팅이 어떻게 동작할지
C, Java, C++ 과는 다르게 JS는 멀티 패러다임 언어
- 절차지향, OOP, 함수형 모두 작성 가능
- 섞어서 사용도 가능
Backwards compatibility
- JS에 새로운 기능이 추가되면, 미래에도 지원되어야 한다
- 웹을 고장내지 않기 위해서!
- 단점: 언어를 변경하거나 확장하기 어렵게 만든다
- 모든 결정이 영구히 적용되기 때문
Not Forward compatible
- JS는 새로운 기능을 추가하면, 과거의 JS 엔진에서는 프로그램 전체가 제대로 동작하지 못할 수 있다
- 최신 버전의 코드는 과거의 엔진에서 작동하지 않는다
- 선언형(마크업)인 CSS, HTML과는 달리 스킵한 부분 때문에 뒤의 코드가 영향을 받을 수 있기 때문!
- ⇒ 문법 버전 문제일 때 해결법: Transpiling
- 코드를 다른 형태로 바꾸는 것 (그러나 결과물도 텍스트 코드)
- Babel
- ⇒ API 버전 문제일 때 해결법: Polyfill
- 과거 환경에게 최신 api의 정의를 제공해 주는 것
- Babel과 같은 transpiler는 보통 필요한 polyfill을 자동으로 제공한다
- 개발자는 깔끔하고 최신 문법으로 코드를 짜는 데 집중하고, 툴이 이전 버전을 지원하는 것을 맡아야 한다
- HTML, CSS는 forward compatible, but not backward compatible
- 인식되지 않으면 skip
What's in an interpretation?
- 컴파일 언어에서 - 최근에는 실행 가능한 결과물의 다양해졌기 때문에, 결과물로 어떤 프로그램(바이너리인지) 산출되었는지는 중요하지 않다
- JS가 인터프리터 언어인지 컴파일 언어인지 판단하는 중요한 근거는 에러를 처리하는 방식임
- 인터프리터 언어에서는 5번 줄의 에러는 1~4번줄을 실행한 다음에 발견됨
- Parsed language(컴파일 언어 포함)는 5번 줄의 에러가 파싱 단계에서 발견됨. 어떤 명령도 실행되기 전에
- JS는 Parsed language
- 실행되기 전에 파싱됨
- 에러도 코드가 실행되기 전에 보고됨
- 그러나 컴파일 언어는 아닌 쪽에 더 가까움
- 최적화된(바이너리) 형태로 변환
- 파싱 ⇒ 최적회된(바이너리)로 변환
- JS 가상 머신에 전달
- 생성된 코드에서 JIT(Just-In-Time) 처리/최적화를 여러 번 통과
- ⇒ 따라서 관점에 따라 컴파일, 인터프리터로 다르게 볼 수 있음
JS 소스의 실행 흐름
- 빌드 프로세스
- Babel로 transpile
- 웹팩으로 묶음
- 그외 다른 빌드 프로세스
- ⇒ JS 엔진으로 전달
- JS 엔진이 코드를 AST로 파싱
- AST: Abstract Syntax Tree. 구문 분석의 결과
- JS 엔진이 AST를 바이트코드(binary intermediate representation)으로 변환
- 최적화하는 JIT 컴파일러가 더 정제함
- JS 가상머신이 프로그램을 실행
⇒ JS는 컴파일 언어다 (저자의 생각)
- 정적인 에러를 코드 실행전에 알려주는 것도 그 근거
웹 어셈블리 (WASM)
- JS의 가장 큰 고민거리는 성능
- 파싱/컴파일되는 속도, 컴파일된 코드가 실행되는 속도 2가지 측면 모두에서
- ASM.js - 모질라 파이어폭스 엔지니어들이 언리얼 엔진 3을 C에서 JS로 포팅할 때 사용한 JS의 subset
- 최적화의 비결: 중요한 타입 정보를 알려줌
- 그러나 직접 개발보다는 다른 언어에서 transpile하기 위한 용도. 타입을 정의하는 주석이 자동으로 삽입됨.
- 웹 어셈블리 (WASM)
- 모질라에서 개발
- JS 엔진에 내재된 딜레이를 피하기 위해 전혀 JS 같지 않은 방법 사용
- 어셈블리처럼 파싱/컴파일 과정 없이 JS 엔진이 실행 가능
- 파싱, 컴파일은 이전에 처리되어야 함
- 배포되는 것은 JS 엔진이 최소한의 처리로 실행할 수 있는 바이너리 프로그램
- 성능 향상 목적
- 추가로 JS가 아닌 언어를 웹에서 처리하는 가능성을 제공하는 목적도 생겨남
- ex) Go는 쓰레드 프로그래밍을 지원하는데, JS에 쓰레드가 없어도 JS 엔진이 실행할 수 있는 코드로 변환할 수 있는 가능성을 제공
- 다른 언어에서 transpile하기 위해 JS에 기능을 추가해야 하는 압박을 줄여줌
- 다른 언어 생태계에 영향 받지 않고 협회에서 JS 기능을 결정할 수 있음. 포팅할 다른 방법이 있기 때문
- 크로스 플랫폼 가상머신으로 진화하고 있음
- WASM은 JS가 아니다
- JS 엔진에서 돌아갈 뿐
- JS는 WASM으로 변환될 수 있는 수많은 소스중 하나일 뿐
- WASM은 정적 타이핑에 의존
- 타입스크립트는 WASM으로 transpile하기 적절하지 않지만, AssemblyScript 등이 JS/TS와 WASM을 연결하려는 시도 중
- WASM은 웹이 할 수 있는 일을 증대시킨다
- 어떤 사람들은 WASM이 JS를 웹에서 없애거나 최소화시킬 것이라고 말함
- 저자는 WASM이 JS를 대체하지는 않을 것이라 주장함
strict mode
- 2009년 ES5에 추가됨. opt-in(동의 의사 밝혀야 하는) 방식
- strict mode의 장점은 비용을 능가하지만, 레거시 코드 베이스와 관습은 잘 바뀌지 않아 10년이 지난 지금도 프로그래머들 사이에 기본이 되지 못함.
- 기능의 제약보다는, JS 엔진이 가장 잘 최적화할 수 있고 효율적으로 코드를 실행하게 해주는 가이드로 받아들여야 함
- 팀 작업에서 실수 예방
- 구문 오류는 아니지만 컴파일 오류인 것을 제어함
- 예를 들면 같은 파리미터 이름
- 마인드셋: strict mode는 linter처럼 JS의 퀄리티와 성능을 가질 수 있도록 상기시켜 주는 도구이다
"use strict"
- 하나의 파일에서 위 코드로 적용
- 함수 스코프에서도 가능
- 그러나 조금씩 변환할 때 아니면 파일, 프로그램 전체에 적용하는 편이 낫다
- 주의:
;
뒤에 붙이면 에러는 안 나도 strict모드로 변환이 안 됨! - strict mode가 아닌 코드도 transplie되면 strict mode로 변환되기 때문에, 프로덕션된 코드는 대부분 strict mode
'Javascript' 카테고리의 다른 글
JS array의 자료구조는 무엇일까? - V8 엔진에서 JS array 구현 (0) | 2022.09.04 |
---|