ECMAScript와 ES5, ES6의 차이
이번 글에서는 ECMAScript 표준화 과정에 대해 이야기합니다.
자바스크립트의 탄생
1995년
90%의 시장 점유율로 웹 브라우저 시장을 지배하고 있던 넷스케이프 커뮤니케이션즈의 개발로 시작되었다.
정적인 페이지를 이루는 HTML을 동적으로 표현하기 위해 프로그래밍 언어를 개발하고 도입하면서 탄생하였다.
이렇게 탄생한 언어가 Brendan Eich ( 브렌던 아이크 ) 가 개발한 자바스크립트이다.
1996년 3월 ~ 12월
넷스케이프 커뮤니케이션즈는 웹 브라우저인 Netscape Navigator 2 에 도입되었고, 초기 이름은 Mocha 로 불렸었다.
이후, 9월에 LiveScript라는 이름으로 변경되었고 12월에는 마침내 JavaScript로 최종 결정이 되었다.
JavaScript라는 이름을 가지게 된 계기는 당시 대유행했던 Java의 인기에 편승을 위해 변경했다고 한다.
자바스크립트의 표준화
1996년 8월 MS ( Microsoft ) 는 자바스크립트의 파생 버전인 JScript 를 IE 3.0에 탑재하였다.
문제는 JScript와 자바스크립트가 표준화되지 않고 적당히 호환이 되었다는 점이다.
정확히는 각자 개발한 브라우저의 시장 점유율을 위해 각자의 브라우저에서만 동작하는 기능을 넣으며,
경쟁적으로 개발을 시작하여 각 브라우저에 따라 웹 페이지가 정상적으로 동작하지 않고, 크로스 브라우징 이슈가 발생하기 시작한 것 ..
이에 따라 보다 못한 넷스케이프 커뮤니케이션즈가 1996년 11월 ECMA 인터네셔널에 자바스크립트의 표준화를 요청하게 되었고,
1997년 7월, ECMA-262라 불리는 자바스크립트의 표준 ECMAScript 1의 명세가 완성되게 되었다.
여기서 ECMAScript란 Ecma Internatinal이 ECMA-262 기술 구격에 따라 정의하고 있는 표준화된 프로그래밍 언어를 말한다.
이후 1999년 ECMAScript 3 ( ES3 ) 가 발표되었고,
10년 만인 2009년 출시된 ECMAScript 5 ( ES5 ) 가 HTML5와 함께 표준안으로 발표되었다.
2015년에는 ECMAScript 6 ( ES6 ) 가 공개되었고 범용 프로그래밍 언어로서 갖추어야 할 let, const 키워드나
화살표 함수 ( Arrow Function ), Class, Module 등과 같은 기능을 도입하는 큰 변화가 생기게 되었다.
버전 | 출시년도 | 특징 |
ECMAScript 1 ( ES1 ) | 1997 | 초판 |
ECMAScript 2 ( ES2 ) | 1998 | ISO / IEC 국제 표준과 동일한 규격을 적용 |
ECMAScript 3 ( ES3 ) | 1999 | 정규 표현식, try ~ catch 예외 처리 |
ECMAScript 5 ( ES5 ) | 2009 | HTML5와 함께 발표된 표준안 ( JSON, strict mode, filter, reduce, some, every ) |
ECMAScript 6 ( ES6 ) | 2015 | let, const, Class, Arrow Function, Template Literal .. 등 |
'' | 2016 | Arrow.prototype.includes, String.prototype.includes, 지수 연산자 |
'' | 2017 | async / await, Object 정적 메소드 ( values, entries .. ) |
'' | 2018 | Object Rest / Spread 프로퍼티 |
ES6 이후의 업데이트는 매년 공개할 것으로 예고되었고, 이처럼 지속적으로 버전을 업데이트하는 모습을 볼 수 있다.
JavaScript Versions
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com
ES5, ES6를 정리하기 전 요약
넷스케이프사에서 정적인 HTML을 동적으로 구현하기 위해,
Mocha, LiveScript, JavaScript의 순서로 지속적으로 개발하며 브라우저에 도입하면서 지금의 JavaScript가 탄생하였다.
이에 따라, 경쟁적인 부분으로 시장 점유율을 위해 MS사에서 JavaScript의 파생 언어 JScript를 개발하였다.
하지만, 각자의 브라우저에서만 동작하는 기능을 추가함으로서 각 언어끼리의 동작이 원활하지 않아 크로스 브라우징 이슈가 발생했다.
이를 해결하기 위해 넷스케이프사에서는 Ecma International에 표준화를 요청하였고,
ECMA-262 기술 규격에 따라 표준화된 ECMAScript 1 초판으로부터 지금의 ES5, ES6 가 있게 되었다.
이후, 매년 버전업이 이루어지며 ES6 이후로 발생하는 버전업은 매년 공개할 것으로 예고되게 되었다.
ES5와 ES6의 차이점
위에서 설명한 대로 ES는 ECMAScript의 약자로 ECMA-262 기술 규격에 따라 표준화된 프로그래밍 언어를 말한다.
ES5와 ES6는 각 2009년, 2015년에 업데이트 되었고, 업데이트에 따라 신규 기능이 적용되었다.
ES6 이전에는 var 키워드가 쓰였고, 현재 흔히 사용하는 let, const 키워드를 찾아볼 수 없었다.
ES5에서는 var가 유일하게 변수를 선언할 수 있는 방법이였으며 아래와 같은 특징 때문에 여러가지 문제를 일으켰다.
ES5
1. ES5 ( ECMAScript 5 ) 는 var 키워드로 변수를 선언하고 관리했다.
2. 변수의 중복 선언이 허용되었다. ( 의도하지 않은 변수의 변경이 이루어질 수 있다 )
3. var 키워드에 대한 생략 허용되었다. ( 암묵적인 변수를 만들어 낼 가능성이 크다 )
4. 변수 호이스팅 ( 변수를 선언하기 이전에 참조가 가능하다. )
이처럼 시한 폭탄과 같은 개발이 이루어질 수도 있어 유지보수나 런타임 환경에서 문제를 일으킬 확률이 높았습니다.
또한, 코드의 복잡성이 오를 수록 이러한 문제는 더욱 드러나 보였고 변수와 상수 구분 조차도 불가능했다.
ES6
let, const 키워드
변수와 상수 선언이 가능하다.
Template Literal
` 백틱으로 여러 줄에 거쳐 작성할 수 있어 문자열에 대한 처리가 간편해졌다.
// ES5
var char = "안녕하세요, " + name + "님";
// ES6
const char = `안녕하세요, ${name}님`;
const element = `<div>
<div>
<span>안녕하세요, ${name}님</span>
</div>
</div>`;
Default Parameters
함수의 파라미터 ( 매개변수 ) 정의 부분에 default 값을 정의할 수 있게 되었다.
const sum = (a = 0, b = 0) => {
return a + b;
}
sum(5, 5); // 10
sum(); // 0
Destructing Assignment
배열 혹은 객체를 분해하여 그 값을 새로운 변수에 바인딩하도록 하는 표현식
const arr = ["blueberry", "apple", "banana"];
const [a, b, c] = arr;
console.log(b); // apple;
const object = { name: "sojiwoo" };
const { name } = object;
console.log(name); // sojiwoo
Enhanced Object Literals
객체 정의 방식을 개선한 문법이다.
const key = 'name';
const object = { key }; // object = { key: 'name' };
const key = 'name';
const newObject = {
[key]: 'sojiwoo',
['b' + 'ye']: 'byebye',
} // newObject = { name: 'sojiwoo', bye: 'byebye' };
Arrow Function
화살표 함수 표현식은 함수 표현에 있어 구문이 짧고 자신의 this, args, super 을 바인딩하지 않는다.
화살표 함수는 항상 익명이며, 메서드로 쓰이지 않는 함수로서 적합하다.
const function = () => {}; // 기본 표현
const function = () => console.log('data'); // {} 은 생략이 가능하다.
function(); // data
const function = (a, b) => a + b; // {} 를 생략하면 return과 같은 동작을 한다.
function(1, 2) // 3;
const function = (a, b) => { return a + b }; // {} 안에서는 return을 통해 값을 반환해야 한다.
function(1, 2) // 3;
const function (a, b) => ({ first: a, second: b }); ()을 씀으로서 객체를 리턴할 수 있다.
function(1, 2); // { first: 1, second: 2 }
const function (a, b) => { a + b }; // {} 안에서 return을 명시하지 않으면 값이 반환되지 않는다.
function(1, 2); // undefined;
Promise
JavaScript의 비동기 처리에 사용되는 객체이며 Promise 이전의 비동기 처리는 Callback 함수를 설정하는 방식으로 이루어졌고,
비동기 처리를 연속적으로 하는 경우 Callback Hell이라고 불리는 현상이 발생했다.
const getData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("data");
}, 1000);
reject(new Error("응답이 없습니다"));
});
};
getData().then((data) => {
console.log(data);
}).catch((err) => {
console.log(err);
});
Promise의 상태는 아래와 같이 나뉜다.
Pending ( 대기 ), Fullfilled ( 이행 ), Rejected ( 실패 )
Class
ES6부터는 JavaScript도 Class와 Class 상속을 지원한다.
ES6 이전에는 생성자 함수와 프로토타입을 통해 정의했다.
// ES6 이전 ..
function Person(name, age) => {
this.name = name;
this.age = age;
}
Person.prototype.getAge = function() {
return "저의 나이는 " + this.age + "입니다.";
};
const person = new Person('소지우', 24);
console.log(person.getAge()); // 저의 나이는 24입니다.
// ES6 이후
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
getAge() {
return `저의 나이는 ${this.age}입니다.`;
}
}
const person = new Person('소지우', 24);
console.log(person.getAge()); // 저의 나이는 24입니다.
Module
import, export 를 통해 하나의 자바스크립트 파일이 모듈이 될 수 있다.
다른 모듈을 가져와 사용할 수 있고, 반대로 내보내는 작업이 가능하다.
단일 객체 내보내기와 복수 객체로 내보내 불러올 수 있는 방법도 가능하다.
// ES6 이전 모듈 내보내기, 불러오기
// 내보내기
function sum(a, b) {
return a + b;
}
module.exports = { sum };
// 불러오기
const { sum } = require("./math");
// ES6 모듈 내보내기, 불러오기
// 내보내기
const sum = (a, b) => {
return a + b;
}
export { sum }; // 복수
or
export default sum; // 단일
// 불러오기
import { sum } from "./math.js";
or
import sum from "./math.js";
var, let ,const 차이점
var
ES6 이전에는 변수를 선언하는 방법으로 var 키워드를 사용해야 했다.
이러한 var는 중복 선언과 생략 그리고 호이스팅으로 인해 선언문 이전에 선언해도 선언이 가능했다.
이러한 이유로는 var의 선언은 자바스크립트 엔진이 전역 코드를 평가하면서 변수를 등록하는데 이때, undefined으로 초기화를 한다.
그래서 선언문 이전에도 호출하여도 "undefined" 이라는 값으로 호출이 가능하다.
let, const
ES6부터는 let, const라는 키워드가 추가되었다.
동일하게 호이스팅이 발생하지만, undefined으로 초기화하지 않기 때문에 선언문 이전에 호출하고자 하면 refference error가 발생한다.
이 현상을 TDZ ( Temporal Dead Zone ) 일시적 사각 지대라 부른다.
그리고 var 키워드처럼 유연했던 점을 바꿔 let과 const로 변수와 상수를 구분할 수 있게 했다.
let으로 선언된 변수는 값을 재할당할 수 있고, const로 선언된 상수는 값의 재할당이 불가능하다.
두 키워드는 재할당 가능 여부에 차이점이 있지만, 재선언은 불가능하다.
자바스크립트의 탄생 배경과 변화를 살펴보며 ..
자바스크립트는 ECMAScript로 ECMA-262 기술 규격에 따라 표준화가 진행됨에 따라 성장을 겪었고,
어른스러운 언어로서 발돋움하게 되었다.
이전에는 시장 점유율 차지를 위해 JavaScript와 JScript가 각 브라우저에서 서로 다른 기능을 가지게 되고,
결국은 크로스 브라우징이라는 문제가 발생하여 개발자들이 이를 해결하기 위한 골머리를 앓게 되었다.
하지만, ECMAScript 표준화된 프로그래밍 언어로서 지금의 JavaScript가 있게 되었다.