- 기술
- JavaScript
ECMAScript 버전 훑어보기

무슨 글을 쓰려고 하나요?🔗
자바스크립트는 제가 가장 사랑하는 언어이자 모던 웹의 베이스입니다. 이 자바와 이름이 비슷하여 자바스크립트는 오해도 많이 받고, 브라우저 내에서만 사용되던 비운의 언어였지만, 현재는 그 어떤 언어보다 많은 사랑을 받고, 모든 플랫폼을 아우르는 언어로 성장했습니다.
그 배경에는 스크립트 구현체인 JavaScript의 표준이자 규칙인 ECMAScript의 발전이 있었기 때문입니다. 이 글에서는 ECMAScript의 역사를 간략하게 살펴보려 합니다. 과거 버전부터 최신 버전까지, 무엇이 변하고 어떻게 발전해왔는지 함께 살펴봅시다.
ES1, ES2, ES3🔗
탄생과 성장
1997년, JavaScript는 자신의 표준인 ES1을 세상에 선보였습니다. 최초의 ECMAScript는 자바스크립트의 기본 구조를 담고 있었지만, 아직 개선할 점이 많았습니다. 그러나 이 버전이 가진 중요한 의미는, 표준을 통해 프로그래밍 언어의 기반을 닦아준 점입니다.
ES2는 1998년에, ES3는 1999년에 각각 출시되었습니다. ES3에서는 정규 표현식과 try
/catch
등 중요한 개념들이 도입되어, 오류 처리와 데이터 검증에 있어서 큰 발전이 있었습니다. 하지만 이런 중요한 추가사항에도 불구하고, 여전히 JavaScript는 더 많은 기능이 필요했습니다.
ES4🔗
야심차지만 빛을 보지못한 버전
ES4는 거창한 계획을 세웠지만, 결국 세상에 공개되지 못하였습니다. 이 버전에서는 타입, 모듈 등 많은 새로운 기능을 추가하려 했지만, 그러한 변화가 너무 컸기 때문에 결국 이는 취소되었습니다. 그러나 이 과정에서 나온 아이디어들은 이후 버전들에게 많은 영향을 끼쳤습니다.
ES5🔗
안정화와 기능의 보완
ECMAScript 5, 흔히 ES5로 알려져 있습니다,는 2009년에 승인되어 널리 사용되고 있으며, ECMAScript의 큰 표준 업데이트 중 하나입니다. 이 버전에서 몇 가지 중요한 기능이 추가되었으며, 아래에 주요 기능에 대해 상세히 설명하겠습니다.
'use strict'🔗
ES5에서 도입된 'use strict'는 코드에 더 엄격한 오류 검사를 적용하는 방법입니다. 이 모드는 JavaScript에 안전하지 않은 동작을 금지하므로, 실수로 전역 변수를 생성하거나, 삭제할 수 없는 속성을 삭제하려고 시도하거나, 변수 또는 매개변수 이름을 중복 사용하는 등의 실수를 방지할 수 있습니다.
JSON 지원🔗
ES5는 JSON 데이터를 직접적으로 처리할 수 있도록 JSON.stringify()와 JSON.parse() 메소드를 도입했습니다. 이전 버전에서는 JSON 데이터를 처리하려면 외부 라이브러리가 필요했지만, ES5에서는 기본적으로 지원하기 때문에 JSON 데이터의 인코딩과 디코딩이 훨씬 간단해졌습니다.
Array 메소드🔗
ES5는 배열 처리를 위한 많은 새로운 메소드를 도입했습니다. 예를 들어, .forEach(), .map(), .filter(), .reduce(), .every(), .some() 등의 메소드를 이용하면, 배열을 다루는 작업이 훨씬 간단해지고 코드의 가독성이 향상됩니다.
Object.defineProperty()🔗
Object.defineProperty()는 객체의 새로운 속성을 직접 정의하거나 이미 있는 객체의 속성을 수정할 수 있게 해주는 메소드입니다. 이 메소드를 이용하면 객체 속성의 get, set 액세서를 설정하거나, 속성을 열거할 수 없도록 설정하는 등의 세부적인 객체 속성 설정이 가능해졌습니다.
ES6/ES2015🔗
이 버전은 JavaScript의 가장 유명한 업데이트입니다. 이전 버전과 비교해서 혁신적인 변화가 많이 일어났고, 이 업데이트 덕분에 편하고 더 안전하게 프로그래밍할 수 있게 된 부분이 많습니다. 다음은 ES6에서 도입된 주요 기능들입니다.
let과 const🔗
ES6에서는 'let'과 'const' 두 가지 새로운 변수 선언 키워드가 도입되었습니다. 'var'와 달리 'let'과 'const'는 블록 스코프를 가지므로, 코드의 가독성과 예측 가능성을 향상시키고 실수를 줄이는데 큰 도움이 됩니다.
화살표 함수 (Arrow Functions)🔗
ES6는 또한 화살표 함수를 도입했습니다. 화살표 함수는 간결한 문법을 제공합니다. 화살표함수의 도입은 복잡한 'this' 개념을 단순화하여 this
바인딩에 대한 혼란을 줄일 수 있게 되었습니다. 일반 함수와 다르게, 화살표 함수는 자신만의 'this'를 생성하지 않으며, 상위 스코프의 'this'를 사용합니다.
클래스 (Classes)🔗
ES6에서 클래스는 객체 지향 패턴을 JavaScript에 더 쉽게 적용할 수 있도록 하는데 있어 핵심적인 역할을 합니다. 이전 버전에서는 복잡한 프로토타입 기반 상속 패턴을 사용해야 했지만, ES6의 클래스를 이용하면 보다 간결하고 직관적인 문법으로 객체 지향 프로그래밍을 구현할 수 있습니다.
Promise🔗
Promise는 비동기 처리를 보다 편리하게 할 수 있도록 도와주는 객체입니다. 이전 버전에서는 비동기 로직을 처리하기 위해 콜백 함수를 사용했지만, 이는 코드가 복잡해지고 가독성이 떨어지는 콜백 지옥을 만들 수 있습니다. ES6의 Promise를 이용하면 비동기 로직을 체인으로 연결하여 간결하고 가독성 좋은 코드를 작성할 수 있습니다.
ES7/ES2016🔗
ES7은 큰 변화를 가져오진 않았지만, 지수 연산자(**
)가 추가되었고 Array.prototype.includes 라는 사랑받는 함수도 추가되었습니다.
예를 들어, 이전에는 배열에서 특정 요소의 존재를 확인하기 위해 indexOf
를 사용했지만, 이것은 값이 배열에 없을 때 -1을 반환하는 하기 때문에 평가후 비교에 번거로움이 있었습니다. 하지만 이번 버전에서 도입된 includes
메소드를 사용하면, 특정 요소의 존재 여부를 true/false
값으로 간단하게 확인할 수 있게 되었습니다.
ES8/ES2017🔗
Async/Await의 등장
ES8에서는 async
/await
가 도입되어 비동기 처리를 더욱 편리하게 만들어주었습니다. ES6에서 도입된 Promise
는 비동기 처리를 더욱 쉽게 만들어주었지만, 여전히 then
체이닝이 복잡해지고 에러 처리가 어려운 단점이 있었습니다. async
/await
는 이러한 문제를 해결하고, 비동기 코드를 마치 동기 코드처럼 간결하게 작성할 수 있도록 도와주었습니다.
ES9/ES2018🔗
Rest, Spread 연산자와 비동기 이터레이션
ES9에서는 여러가지 흥미로운 기능들이 추가되었습니다. 그 중에서도 rest
와 spread
연산자의 도입은 객체와 배열을 다루는 방법을 바꾸어 주었습니다.
spread
연산자를 사용하면 배열이나 객체의 요소를 쉽게 복사하거나 병합할 수 있습니다. 이전에는 Object.assign()
이나 Array.concat()
을 사용하여 객체나 배열을 복사하거나 병합해야 했지만, spread
연산자를 이용하면 간단하게 처리할 수 있게 되었습니다.
비슷한 맥락에서 rest
연산자를 이용하면 함수의 인자를 배열로 쉽게 만들 수 있습니다. 이전에는 arguments
객체를 사용해야 했지만, 이 방법은 배열이 아니기 때문에 불편한 점이 있었습니다. rest
연산자를 이용하면 이러한 불편함이 사라집니다.
또한, ES9에서는 비동기 이터레이션과 제너레이터를 도입하였습니다. 이는 비동기 데이터 스트림을 쉽게 다룰 수 있게 해주었습니다.
ES10/ES2019🔗
Array.prototype.flatMap, Object.fromEntries
ES10에서는 여러 유용한 기능들이 추가되었습니다. 그 중에서도 flatMap
메소드와 Object.fromEntries
함수는 개발자들에게 매우 유용한 도구로 인식되었습니다.
flatMap
메소드는 배열의 각 요소에 함수를 적용한 후, 결과를 새로운 배열로 평탄화합니다. 이는 map
메소드와 flat
메소드를 연결하는 것과 동일한 결과를 반환합니다.
Object.fromEntries
함수는 키-값 쌍의 배열을 객체로 변환합니다. 이는 Object.entries
함수와 반대의 작업을 합니다.
ES11/ES2020🔗
BigInt, Promise.allSettled, Nullish Coalescing
BigInt
는 JavaScript에서 아주 큰 숫자를 안전하게 다룰 수 있는 새로운 프리미티브 형식입니다. JavaScript의 기존 Number
타입은 IEEE 754 표준을 따르기 때문에 안전하게 다룰 수 있는 가장 큰 정수는 2^53 - 1입니다. 그러나 BigInt
를 사용하면 이 제한을 넘어 아주 큰 정수를 안전하게 다룰 수 있습니다.
Promise.allSettled
메소드는 모든 프로미스가 결정되었을 때 (즉, 성공하거나 실패하거나) 완료된 프로미스 배열을 반환합니다. 이전의 Promise.all
메소드는 하나라도 실패하면 즉시 실패하지만, allSettled
메소드는 모든 프로미스가 완료될 때까지 기다립니다.
Nullish Coalescing
연산자 ??
는 좌측 피연산자가 null이나 undefined일 때만 우측 피연산자를 반환합니다. 이전에는 ||
연산자를 사용하여 비슷한 효과를 낼 수 있었지만, ||
연산자는 좌측 피연산자가 falsy한 값일 때도 우측 피연산자를 반환하므로 문제가 발생할 수 있습니다. ??
연산자를 사용하면 이러한 문제를 피할 수 있습니다.