1. 자바스크립트라는 언어
프로그래밍이란 무엇인가
프로그래밍은 컴퓨터에게 일을 시키는 커뮤니케이션이다.
그런데 컴퓨터에게는 사람과 결정적으로 다른 점이 하나 있다. 눈치가 전혀 없다는 것이다.
친구에게 “목마른데 뭐 좀 사다 줘”라고 하면, 친구는 알아서 편의점에 가서 알아서 음료수를 골라 온다. 컴퓨터에게는 이 “알아서”가 단 하나도 통하지 않는다.
그래서 프로그래밍의 첫 단계는 코드를 치는 것이 아니라, 시키고 싶은 일을 스스로 정확하게 정의하는 것이다.
자판기로 이해하는 컴퓨팅 사고
자판기가 하는 일을 사람의 언어로 말하면 한 문장이다. “돈 받고 음료를 준다.”
이것을 컴퓨터가 실행할 수 있는 수준으로 쪼개면 이렇게 된다.
금액을 기억한다
투입된 금액의 합계를 저장해 둔다.
버튼 입력을 판단한다
버튼이 눌리면 합계가 음료 가격 이상인지 확인한다.
조건에 따라 나눈다
충분하면 음료를 내보내고 합계에서 가격을 뺀다. 부족하면 아무 일도 하지 않는다.
반환을 처리한다
반환 레버가 당겨지면 남은 금액을 돌려주고 합계를 0으로 만든다.
여기서 주목할 것은 하나다. “돈이 충분하면”이라는 모호한 말이 “합계 ≥ 가격”이라는 판단 가능한 조건으로 바뀌었다.
큰 문제를 작은 단계로 쪼개고, 모호한 표현을 판단 가능한 조건으로 바꾸는 것. 이런 사고방식을 컴퓨팅 사고Computational Thinking라 하며, 이것이 프로그래밍의 본체다.
코드는 이 설계를 받아 적은 결과물일 뿐이다. 그리고 앞으로 배울 문법은 전부 이 설계를 표현하기 위한 도구다.
| 설계에서 필요한 것 | 그것을 표현하는 문법 | 배우는 편 |
|---|---|---|
| 값을 저장한다 (합계) | 변수 | 3편 |
| 판단하고 반복한다 (합계 ≥ 가격?) | 제어문 | 8편 |
| 절차를 묶어 재사용한다 | 함수 | 9편 |
문법만 맞으면 되는 게 아니다
“투명한 분노가 조용히 달린다.” 한국어 문법상 완벽한 문장이지만 아무 의미가 없다. 코드에서도 똑같은 일이 벌어진다.
const price = '삼천원';
console.log(price * 2); // NaN문법 오류는 하나도 없다. 하지만 가격을 계산하려던 의도는 실패했다. 곱셈이 가능한 숫자가 아니라 문자열을 담았기 때문이다.
NaN — Not a Number의 약자. “숫자로 계산할 수 없었다”는 뜻의 특수한 값이다. 숫자가 아닌 값으로 산술 연산을 하면 에러 대신 이 값이 나온다. (5편)
정리하면 코드는 두 가지를 모두 갖춰야 한다.
- 문법syntax — 언어의 규칙에 맞는가
- 의미semantics — 의도한 일을 실제로 해내는가
이 시리즈에서 문법을 배울 때마다 “이 문법은 어떤 문제를 풀려고 존재하는가” 를 함께 묻는 이유다.
자바스크립트의 탄생
1995년, 웹 브라우저 시장의 90%를 장악한 회사는 넷스케이프였다.
당시 웹페이지는 움직임이 없는 문서에 가까웠다. 넷스케이프는 웹페이지에 동적인 기능을 넣을 가벼운 언어가 필요하다고 판단했고, 개발을 브렌던 아이크Brendan Eich에게 맡겼다.
첫 프로토타입이 나오기까지 걸린 시간은 단 열흘이었다. 이름은 Mocha → LiveScript → JavaScript 순으로 바뀌었다.
자바(Java)와의 관계는? 아무 관계 없다. 당시 인기가 높던 자바의 유명세에 올라탄 마케팅 작명일 뿐이며, “인도와 인도네시아만큼 다르다”는 농담이 있을 정도로 서로 다른 언어다.
열흘 만에 태어난 언어답게 어색한 설계도 남아 있다. 뒤에서 만날 var의 이상한 동작 같은 것들이다.
동시에 다른 언어에서 가져온 두 가지 유전자도 품고 태어났다.
- 프로토타입 기반 상속 — 이미 만들어진 객체를 원형으로 삼아 그 기능을 물려받는 방식 (17편)
- 일급 함수 — 함수를 값처럼 다룰 수 있다는 뜻. 변수에 담고, 다른 함수에 넘길 수 있다 (11편)
지금 이해하지 못해도 괜찮다. 자바스크립트가 겉보기보다 깊은 언어라는 것만 알아두자.
표준의 탄생 — ECMAScript
브라우저 전쟁
1996년, 마이크로소프트가 자바스크립트를 모방한 JScript를 인터넷 익스플로러에 탑재한다.
두 회사는 점유율 경쟁을 위해 자기 브라우저에서만 동작하는 기능을 경쟁적으로 추가했다. 결과는 재앙이었다. 같은 코드가 브라우저마다 다르게 동작하는 크로스 브라우징 이슈가 웹 전체를 괴롭히게 된 것이다.
나라마다 콘센트 모양이 달라 여행 때마다 어댑터를 챙겨야 하는 상황과 같다. 당시 개발자들은 브라우저별로 다른 코드를 따로 짜는, “어댑터를 코드로 만드는” 일을 해야 했다.
표준화
이 혼란을 끝내기 위해 1997년, 표준화 기구 ECMA 인터내셔널에서 표준 사양 ECMA-262가 만들어졌다. “JavaScript”라는 이름에 상표권 문제가 있었기 때문에, 표준으로서의 언어 이름은 ECMAScript가 되었다.
사양specification, 스펙 — “이 언어는 이렇게 동작해야 한다”를 문서로 못 박아 둔 설계도. 브라우저 제조사들이 이 문서를 보고 각자 구현하기 때문에, 어느 브라우저에서든 같은 코드가 같게 동작한다.
| 버전 | 연도 | 핵심 |
|---|---|---|
| ES3 | 1999 | 정규 표현식, try…catch |
| ES5 | 2009 | JSON, strict mode, 배열 메서드(forEach, map 등) |
| ES6 (ES2015) | 2015 | let/const, 클래스, 화살표 함수, 프로미스, 모듈 |
| ES2016~ | 매년 | 매년 6월경 소규모 업데이트 |
| ES2026 | 2026 | 현재 최신. Temporal(새 날짜 API) 등 |
표를 외울 필요는 없다. 기억할 것은 하나다. ES6(2015)가 최대 분수령이다.
이때 현대적인 언어가 갖춰야 할 기능이 대거 도입되었고, 오늘날 실무 코드의 기본 형태가 만들어졌다. 이 시리즈도 ES6 이후 문법을 기준으로 삼는다.
그 이후의 연간 업데이트는 “편의 기능 몇 개 추가” 수준이라, 필요할 때 찾아보면 충분하다.
조연에서 주연으로 — 다섯 번의 변곡점
초기의 자바스크립트는 조연이었다. 중요한 로직은 전부 서버에서 돌았고, 브라우저는 서버가 준 HTML을 화면에 그리는 역할에 머물렀다.
렌더링 — 코드나 데이터를 사람이 볼 수 있는 화면으로 그려내는 일. 서버 / 클라이언트 — 서버는 데이터를 보관하고 요청에 응답하는 컴퓨터, 클라이언트는 그것을 요청해 쓰는 쪽(우리의 브라우저)이다.
그런 자바스크립트가 웹의 주연이 되기까지 결정적인 사건이 다섯 번 있었다.
① Ajax (1999~)
그 전까지는 내용이 조금만 바뀌어도 HTML 전체를 새로 받아 화면 전체를 다시 그렸다. 페이지를 이동할 때마다 화면이 하얗게 깜박이던 이유다.
Ajax는 서버에서 필요한 데이터만 받아 바뀐 부분만 다시 그리는 것을 가능하게 했다. 2005년 구글 맵스가 이 방식으로 지도를 매끄럽게 움직여 보이며 “브라우저에서 이게 된다고?”라는 충격을 안겼다.
Ajax — Asynchronous JavaScript and XML의 약자. 비동기asynchronous — 요청을 보내 놓고 응답을 기다리는 동안 다른 일을 계속할 수 있는 방식. 음식을 주문하고 서서 기다리는 대신 자리에 앉아 다른 일을 하는 것과 같다. (21편)
② jQuery (2006)
웹 문서를 자바스크립트로 조작하는 일은 번거로웠고, 브라우저마다 다르게 동작하는 문제도 여전했다.
jQuery는 이를 짧고 일관된 코드로 해결하며 웹 개발의 대중화를 이끌었다. 지금은 신규 프로젝트에서 거의 쓰지 않지만, 그 편의 기능 상당수가 이후 표준에 흡수되었다.
DOM — Document Object Model의 약자. 브라우저가 HTML 문서를 읽어 자바스크립트가 다룰 수 있는 객체 구조로 바꿔 놓은 것이다. 버튼의 글자를 바꾸거나 요소를 추가·삭제하는 일이 전부 DOM 조작이다. (36편)
③ V8 엔진 (2008)
구글이 만든 고성능 자바스크립트 엔진이다.
V8 덕분에 실행 속도가 비약적으로 빨라지자 서버에서 하던 일이 대거 브라우저로 넘어왔다. 프론트엔드 개발이 지금의 위상을 갖게 된 출발점이다.
자바스크립트 엔진 — 자바스크립트 코드를 해석하고 실행하는 프로그램. 모든 브라우저에 하나씩 들어 있다. 크롬은 V8, 파이어폭스는 SpiderMonkey, 사파리는 JavaScriptCore를 쓴다.
④ Node.js (2009)
V8을 기반으로 만들어진, 브라우저 바깥에서 자바스크립트를 실행하는 환경이다.
이때부터 자바스크립트는 서버와 명령줄 도구까지 활동 범위를 넓혔고, 프론트엔드와 백엔드를 한 언어로 개발하는 것도 가능해졌다. 다음 편에서 직접 설치한다.
런타임runtime / 실행 환경 — 코드가 실제로 돌아가는 무대. 브라우저와 Node.js가 자바스크립트의 두 무대다. CLI — Command Line Interface의 약자. 마우스 대신 명령어를 입력해 조작하는 터미널 방식의 도구.
⑤ SPA 프레임워크 (2010년대~)
애플리케이션 규모가 커지면서 화면을 부품 단위로 조립하는 방식이 주류가 되었고, React·Vue.js 같은 프레임워크가 등장해 표준적인 개발 방식이 되었다.
SPA — Single Page Application의 약자. 페이지를 새로 불러오지 않고 한 페이지 안에서 화면을 바꿔 끼우는 방식. 컴포넌트 — 버튼, 카드, 헤더처럼 재사용 가능한 화면 조각. 레고 블록을 조립하듯 화면을 만든다. 프레임워크 vs 라이브러리 — 라이브러리는 내가 필요할 때 불러 쓰는 도구, 프레임워크는 정해진 틀 안에 내 코드를 끼워 넣는 구조다.
프레임워크는 유행이 바뀌지만, 그 아래의 자바스크립트는 바뀌지 않는다. 이 시리즈가 프레임워크가 아닌 언어 자체를 파고드는 이유다.
JavaScript와 ECMAScript의 차이
두 용어가 계속 나왔으니 관계를 정리하자. JavaScript가 더 큰 개념이다.
- ECMAScript — 표준(ECMA-262)이 정의한 언어의 핵심 문법. 값, 타입, 객체, 함수 등
- JavaScript — ECMAScript + 실행 환경이 제공하는 API. 브라우저라면 DOM, fetch 같은 Web API
API — Application Programming Interface의 약자. “이 기능을 쓰려면 이렇게 요청하세요”라고 정해 둔 사용 창구다. 식당의 메뉴판과 비슷하다. 주방이 어떻게 요리하는지 몰라도 메뉴판대로 주문하면 음식이 나온다. Web API — 브라우저가 자바스크립트에게 열어 준 창구. 화면 조작(DOM), 네트워크 통신(fetch), 저장소 등이 여기 속한다.
이 구분이 왜 중요한지는 실무에서 바로 체감된다.
브라우저
alert('안녕'); // 경고창이 뜬다alert는 브라우저가 제공하는 Web API이므로 정상 동작한다.
같은 코드인데 결과가 다르다.
alert는 언어(ECMAScript)의 기능이 아니라 브라우저(Web API)의 기능이기 때문이다.
“이 기능은 언어의 것인가, 환경의 것인가?”
이 감각이 앞으로 계속 필요하다. 두 환경의 차이는 다음 편에서 직접 확인한다.
자바스크립트의 성격 네 가지
① 브라우저에서 동작하는 사실상 유일한 언어
HTML이 구조, CSS가 모양을 맡는다면 동작은 자바스크립트의 몫이다.
파이썬이 아무리 좋은 언어여도 브라우저는 그것을 실행하지 못한다. 웹이라는 거대한 플랫폼의 유일한 언어라는 점이 이 언어 최대의 자산이다.
② 인터프리터 언어
| 방식 | 동작 | 비유 |
|---|---|---|
| 컴파일러 | 실행 전에 코드 전체를 기계어로 번역해 둔다 | 책을 통째로 번역해 출판하는 번역가 |
| 인터프리터 | 실행하면서 그때그때 해석한다 | 말하는 즉시 옮기는 동시통역사 |
자바스크립트는 인터프리터 방식이라 별도의 컴파일 과정 없이 바로 실행된다. “그래서 느리다”는 이제 옛말인데, V8 같은 모던 엔진이 JIT 기법으로 속도 문제를 해결했기 때문이다.
기계어 — CPU가 직접 이해하는 0과 1로 된 명령. 사람이 쓴 코드는 결국 이 형태로 번역돼야 실행된다. JIT — Just-In-Time의 약자. 실행 도중에 자주 쓰이는 코드만 골라 기계어로 컴파일해 두는 기법. 동시통역사가 반복되는 표현을 미리 번역해 놓는 것과 같다.
③ 멀티 패러다임 언어
절차를 순서대로 쓰는 명령형, 함수 조합 중심의 함수형, 데이터와 동작을 객체로 묶는 객체지향을 모두 지원한다. 유연하다는 장점이자, 좋은 코드의 기준을 스스로 세워야 한다는 과제이기도 하다.
패러다임 — 코드를 조직하는 사고방식이자 스타일. 같은 문제를 푸는 방법이 여러 갈래라는 뜻이고, 자바스크립트는 그중 어느 것도 강제하지 않는다.
④ 프로토타입 기반 객체지향 언어
자바스크립트는 클래스가 아니라 프로토타입이라는 독자적인 방식으로 객체지향을 구현한다. ES6에서 클래스 문법이 생겼지만, 그 밑바닥에서 실제로 동작하는 것은 여전히 프로토타입이다. (17편, 18편)
이번 편 용어 정리
| 용어 | 정식 명칭 | 한 줄 정의 |
|---|---|---|
| API | Application Programming Interface | 기능을 사용하기 위해 정해 둔 창구 |
| Web API | — | 브라우저가 자바스크립트에게 열어 준 창구 (DOM, fetch 등) |
| DOM | Document Object Model | HTML 문서를 자바스크립트가 다룰 수 있게 객체로 만든 구조 |
| Ajax | Asynchronous JavaScript and XML | 필요한 데이터만 비동기로 받아 화면 일부만 갱신하는 방식 |
| SPA | Single Page Application | 한 페이지 안에서 화면을 바꿔 끼우는 웹 애플리케이션 |
| JIT | Just-In-Time | 실행 도중 자주 쓰는 코드를 기계어로 컴파일하는 최적화 기법 |
| CLI | Command Line Interface | 명령어를 입력해 조작하는 터미널 방식의 도구 |
| NaN | Not a Number | 숫자로 계산할 수 없었음을 뜻하는 특수한 값 |
| 엔진 | JavaScript Engine | 자바스크립트를 해석하고 실행하는 프로그램 (V8 등) |
| 런타임 | Runtime | 코드가 실제로 실행되는 환경 (브라우저, Node.js) |
핵심 요약
- 프로그래밍의 핵심은 문법 암기가 아니라, 문제를 쪼개고 판단 가능한 조건으로 바꾸는 능력이다
- 코드는 문법에 맞는 것을 넘어 의도한 일을 실제로 해내야 한다
- 자바스크립트는 1995년 열흘 만에 태어나, 브라우저 전쟁을 거쳐 ECMAScript라는 표준을 얻었다
- ES6(2015)가 최대 분수령이며, 이 시리즈의 기준이기도 하다
- Ajax → jQuery → V8 → Node.js → SPA를 거치며 조연에서 주연이 되었다
- JavaScript = ECMAScript(문법) + 환경의 API. 언어의 기능인지 환경의 기능인지 늘 구분하자
다음 편에서는 개발 환경을 준비한다. 브라우저와 Node.js의 차이를 눈으로 확인하고, 첫 코드를 직접 실행해 본다.