dansoon.log()
JavaScript의 흐름과 구조를 바라보며 본문
들어가며
자바스크립트는 오랜 시간 동안 ‘기능적인 언어’로 오해받아 왔습니다. 필요하면 쓰고, 문제 생기면 회피하는 도구처럼 사용했습니다.
하지만 개발 환경이 바뀌고, 프론트엔드가 복잡한 애플리케이션 구조를 갖추게 되면서 자바스크립트는 그 한계를 극복하며 스스로 구조를 진화시켜 왔습니다.
이 글에서는 단순한 연대기적 흐름이 아닌, 언어 자체가 어떻게 '구조'와 '패턴'을 받아들이고, 실제 문법으로 진화해왔는지에 집중해 보았습니다.
1. 태생부터 빠른 실행을 위한 구조였다
자바스크립트는 1995년 넷스케이프에서 태어났습니다.
그리고 설계자였던 브렌던 아이크는 단 열흘 만에 이 언어를 완성했습니다.
설계보다는 속도, 철학보다는 실용이 우선이었고 그 결과 JS는 아래와 같은 특징을 가진 언어로 태어났습니다.
- 전역 스코프
- 유연한 타입
- 느슨한 바인딩
<script>
alert('Hello JS');
</script>
처음에는 단순히 문서에 동작을 붙이는 수준이었고 객체지향이나 모듈성은 고려되지 않았습니다.
이런 구조는 이후 브라우저 간 충돌, 호환성 문제, 유지보수의 어려움으로 이어졌습니다.
2. jQuery는 ‘간편한 도구’가 아니라 ‘언어 설계의 시사점’이었다
2006년 jQuery가 등장했을 때 많은 사람들은 그것을 “코드 몇 줄을 줄여주는 도구”로 보았습니다.
하지만 실상은 달랐습니다. jQuery는 자바스크립트의 문법적 불편함, 브라우저 간 비표준 API, DOM 인터페이스 문제를 통합된 인터페이스로 추상화한 도구였습니다.
$('#btn').on('click', () => {
$.ajax({
url: '/data',
success: res => $('#msg').text(res.message),
});
});
이처럼 이벤트 처리, DOM 조작, Ajax 호출 모두가 하나의 인터페이스로 통일되었고,
브라우저에 따라 다른 방식으로 처리해도 개발자는 그 내부를 몰라도 되었습니다.
저는 실무에서 jQuery를 직접 사용한 경험은 없지만,
레거시 프로젝트에서 이를 순수 JavaScript로 치환하는 리팩터링 작업을 수행한 적이 있습니다.
당시 .on() → addEventListener(), $.ajax() → fetch(), .addClass() → classList.add() 등으로 변환하면서,
단순한 문법 차이뿐 아니라 코드 구조 자체가 더 명확하고 예측 가능해졌다는 것을 체감했습니다.
이 과정에서 jQuery는 “그 시대에는 필요했던 합리적인 추상화”였지만, 이제 JS가 그 기능을 품음으로써 언어 자체가 구조적으로 성장해왔음을 실감할 수 있었습니다.
3. ES5에서 ES6로의 진화는 ‘언어적 반성’의 결과였다
ES5(2009)는 엄격 모드("use strict")와 JSON 지원, Array 메서드 정비를 통해 자바스크립트의 첫 정리 작업이었습니다.
그러나 진짜 진화는 ES6(2015)부터 시작됩니다.
const greet = (name = 'JS') => `Hello, ${name}`;
- 블록 스코프(let, const)
- 클래스 문법
- 모듈(import/export)
- 비동기 흐름(Promise, async/await)
- 전개 연산자, 기본값 파라미터
여기서부터 JS는 위와 같은 문법을 통해 이전보다 구조적으로 예측 가능한 언어로 변화하게 됩니다.
실무에서 ES6 이후 문법이 가장 큰 전환점이 되었다고 느낀 순간은 let과 const의 도입이었습니다.
이 둘이 없던 시절에는 실수로 전역 컨텍스트를 더럽히거나, 변수의 재할당 여부를 예측하지 못해 디버깅에 시간을 낭비하는 일이 잦았습니다. 지금은 const를 기본으로 사용하고, 꼭 필요한 경우에만 let을 쓰는 게 팀 내 컨벤션이 되었고, 이 하나만으로도 코드 안정성이 눈에 띄게 개선된 경험이 있습니다.
4. 자바스크립트는 비동기를 언어 수준에서 받아들였다
JS의 가장 복잡한 부분 중 하나는 비동기 처리였습니다.
이전에는 콜백 중첩이 기본이었고, 코드 흐름이 예측 불가능해지는 경우가 많았습니다.
getUser(userId, function (user) {
getPosts(user.id, function (posts) {
render(posts);
});
});
이를 해결한 구조적 전환점이 Promise, 그리고 이어지는 async/await입니다.
const user = await getUser(userId);
const posts = await getPosts(user.id);
render(posts);
이 코드는 단순히 보기 좋을 뿐 아니라 비동기 흐름 자체를 동기적 문맥 안에서 관리하게 만들어 줍니다. 실제로 이 전환은 라이브러리 구조 설계에도 큰 영향을 주었습니다.
5. 자바스크립트는 이제 '제안-채택-실행'의 순환 시스템을 갖추고 있다
이제 자바스크립트는 단순히 브라우저 업체가 정하는 언어가 아닙니다. TC39라는 표준화 위원회가 단계별로 제안을 받고 논의하고, 실험하고, 브라우저에 반영합니다.
- Stage 0: 아이디어
- Stage 1: 기술 정의
- Stage 2: 설계 초안 및 API
- Stage 3: 브라우저 반영 시작
- Stage 4: 최종 승인
최근에 Stage 4에 도달한 예시 중 하나는 Array.prototype.at() 메서드입니다. 이 기능은 index를 음수로 접근하는 직관적인 방식이었고, Polyfill을 통해 실험된 뒤 최종적으로 모든 브라우저에 정식 반영되었습니다.
또한 2025년 6월, ECMAScript 2025가 공식 승인되면서 개발자 생산성을 높이는 실질적인 기능들이 추가되었습니다. 대표적으로 아래와 같습니다.
- Iterator Helper 메서드: .map(), .filter(), .take(), .drop() 등 반복자 기반 데이터 흐름 제어가 가능해졌습니다. 중간 배열 없이 처리할 수 있어 메모리 효율이 개선됩니다.
- JSON 모듈 import: import config from './config.json' with { type: 'json' } 형태로, 별도 설정 없이 JSON 파일을 네이티브로 불러올 수 있습니다.
- Promise.try(): 동기 함수도 catchable한 promise 흐름에 통합할 수 있게 되어 try/catch 블록 없이 예외 처리가 가능해졌습니다.
- Set 연산 메서드: union, intersection, difference, isSubsetOf 등의 집합 연산이 표준 API로 도입되어, 불필요한 배열 변환 없이도 직관적 연산이 가능해졌습니다.
- RegExp.escape(): 사용자 입력을 안전하게 정규식에 삽입할 수 있도록 도와주는 정규식 이스케이프 API가 추가되었습니다.
실제로 저는 Array.prototype.at() 메서드가 도입되기 전까지는 arr[arr.length - 1] 같은 표현을 습관처럼 사용했지만, 그 의미가 명확하지 않아 가독성이 떨어진다는 피드백을 받은 경험이 있습니다. 이후 Stage 4 기능들을 꾸준히 체크하며 코드의 의도를 더 분명히 전달하는 습관이 생겼습니다.
또한 최근 프로젝트에서는 Promise.try()를 사용해 예외 흐름을 보다 일관되게 유지할 수 있는 것도 코드 품질을 높이는 데 도움이 되었습니다.
신기능의 도입은 단순한 문법의 추가가 아니라, 팀 전체의 코드 퀄리티와 생산성을 한 단계 끌어올리는 계기라고 생각합니다.
6. React, Vue, Svelte는 JS 구조를 기반으로 한 다른 해석들입니다
JS는 이제 단순히 DOM을 다루는 언어가 아닙니다. UI와 상태, 반응성, 컴파일 타임까지 다루는 기반 언어가 되었습니다.
React는 상태 기반 UI 흐름을 공식화했습니다.
Vue는 선언성과 직관성의 균형을 시도했습니다. Svelte는 런타임이 아닌 컴파일 타임에 최적화된 DOM을 만들어냅니다.
프레임워크 중에서는 특히 React의 JSX가 자바스크립트 구조의 변화를 가장 극적으로 드러냈다고 느꼈습니다.
로직과 뷰를 한 덩어리로 구성할 수 있다는 것은 단순한 문법적 편의 그 이상이었고, 상태 기반 렌더링을 통해 UI 구성 방식 자체를 근본적으로 바꿔놓은 경험이었습니다.
반면 jQuery의 선언적 이벤트 처리 방식은 지금 돌이켜보면 Svelte의 컴파일 타임 처리 방식과 닮아 있어, “기능의 단순화”보다는 “구조적 철학의 재해석”이 프레임워크마다 다르게 표현되고 있다는 사실을 자주 체감합니다.
7. 타입스크립트는 자바스크립트의 미래를 정의하고 있다
자바스크립트가 구조적으로 성숙해지면서, 이를 더 정형화하려는 시도로 타입스크립트(TypeScript)가 등장했습니다.
2012년 마이크로소프트에 의해 처음 발표된 타입스크립트는, 자바스크립트 위에 정적 타입 시스템과 클래스 기반 객체지향 문법을 더한 상위 언어입니다.
초창기에는 학습 난이도나 설정 복잡도 때문에 일부 대규모 프로젝트에서만 사용되었지만, 최근 몇 년 사이에는 라이브러리, 프레임워크, 툴링 모두가 TS를 기본 전제로 움직이고 있습니다.
저 역시 타입스크립트를 처음 접했을 때는 타입 선언이 오히려 불편하게 느껴졌지만, 점점 팀 단위 협업과 유지보수 상황에서 명확한 계약이 있는 코드가 얼마나 중요한지를 실감하게 되었습니다. 특히 API 스펙이 바뀌었을 때 에디터에서 바로 에러가 발생하는 경험은, 자바스크립트만 썼을 때는 상상하기 힘든 안정감이었습니다.
타입스크립트는 이제 단순한 언어가 아니라, JS를 확장하고 정형화하며 다음 세대로 이끄는 진화의 도구라고 생각합니다.
마무리하며
이 글을 통해 제가 공유하고 싶었던 것은 단순한 연대기가 아닙니다.
자바스크립트가 사용자의 기대, 프레임워크의 압력, 브라우저 생태계의 필요에 따라 어떻게 스스로의 구조를 재해석하며 진화했는가를 관찰한 결과입니다.
jQuery는 단지 편리한 도구가 아니라 JS 문법과 인터페이스의 방향을 바꿔놓은 혁신이었고, ES6 이후 자바스크립트는 스스로 구조를 정의하고, 표준을 생산하며, 다른 언어와 동등한 수준에서 경쟁하는 언어가 되었습니다.
프레임워크는 계속해서 바뀌고 있지만, 그 근간에 있는 JS의 구조적 원리들은 점점 더 명확하고 깊이 있는 방향으로 발전하고 있습니다.
과거의 기술을 단순히 넘기는 것이 아니라, 그 구조를 다시 뜯어보고 재해석하며 현재의 문법에 녹여보는 경험은 개발자에게 중요한 자산이 됩니다. 저 역시 jQuery 기반 코드를 순수 JS로 재구성하면서 언어가 어떤 문제를 해결하며 성장해왔는지를 체감할 수 있었습니다.
참고
- ECMAScript 2025 주요 변경사항 – The Innovators
- TC39 Proposal Tracking: https://tc39.es
'Development > Frontend' 카테고리의 다른 글
쉽게 정리한 Feature-Sliced Design(FSD) 가이드 (5) | 2024.12.17 |
---|---|
import 경로 관리 알아보기 (alias와 barrel 패턴, FSD) (6) | 2024.12.15 |