[Front-End] About ES5 and ES6

Joosi_Cool·2023년 1월 8일
1

Frond-End

목록 보기
7/8
post-thumbnail

ES5, ES6가 뭔데 이렇게들 난리야?

ES5, ES6 뿐 아니라 ES2020, ES3 등등 ES숫자 이렇게 생긴것을 JS를 쓰면서 듣거나 본적이 있을 것이다.

여기서 ESECMAScript 를 줄임말이다. ECMA는 기관 이름이다.

ECMA?
정보와 통신 시스템을 위한 국제 표준화 기구이다. 그냥 쉽게 말해서 우리가 쓰는 프로그래밍 언어 같은 것을 표준화 시키는 것이다. 뒤에 말할 ECMA-262 표준 말고도, C#, C++, JSON 등 우리가 쓰고 있는 것에 대해 혼란을 주지 않기 위해 표준을 만들고 있다.

ES는 ECMA+script이며, 이는 ECMA-262 라는 표준을 따르고 있는 Script언어이다.

이제 할 말이 조금 당황스러울 수 있는데, ES 즉 ECMAScript는 JavaScript의 새로운 이름이다.

기존 ECMA Script가 나오기 전, JS는 매우 혼동이 있었다. 표준화가 이루어지지 않았고, 웹 브라우저에서 동일하게 작용하지 않는 문제가 있었다.

이를 위해 JS에 표준을 만든것이 ECMA Script 인 것이다.

예를 들어보자.

우리나라 각기 다른 지역에 사는 사람들은 모두 한국어를 쓰지만, 지역마다 사투리를 쓴다. 그래서 제주도에 가면 한국말이지만, 우리가 못알아듣는 경우가 많다. 모두 이해할 수 있게 하기 위해 표준어 를 제정했고, 이것이 한국말의 대표가 되었다.

JS도 마찬가지이다. 초기에는 JS도 사투리처럼 쓰는 방법들이 다 달랐고, 다양한 웹브라우저에서 이를 이해하기란 쉽지 않았다. 아니 불가능했다.

그래서 만든것이 ECMA script이다. 이것이 JS의 표준어가 된것이다.



ES는 이해했다. 그런데 ES5? ES6?

한국 표준말이 한번 정해지면, 그게 평생 지속되는가?

새로운 언어들이 나오고, 사람들의 문화에 따라 한국말 또한 계속적으로 게정된다. 새로운 한국 표준말 버전이 나오는 것이다.

ECMA script도 마찬가지이다. 개발자들의 개발하는 추세, 거기에 따른 새로운 기술들의 도입으로 JS 또한 이에 맞춘 개정이 필요하다. 그래서 뒤에 숫자를 붙이며 계속 버전 업그레이드를 한것이다.

i phone 13 → i phone14 이런식으로 말이다.

ES5는 2009년에, ES6은 2015년에 개정되었다. 위에 그림을 보면 ES4가 없는데?? 할 수 있다.

ES4는 정치적인 문제로 삭제 당했다.

개발 초기에 ES3.1을 개발하는 사람과 ES4를 개발하는 사람으로 나뉘었고, 둘한테 갈등이 있었고, ES3.1 쪽이 이겨서 이것이 ES5가 되었다. 이는 그렇게 중요하진 않다. 알아만 두자.

  • 추가적으로 알았으면 하는게 ES2015 = ES6 이며, 이후 개정때에는 연도를 붙인것을 확인할 수 있다. 이는 별 의미는 없고, 이때 이후에 연도마다 배포를 새로했고 배포연도를 강조하고자 이렇게 이름을 정했다고 한다.

좋아. 이름 뜻은 알겠어… ES + 버전이구만.

근데 왜이리 ES5, ES6에 언급이 그렇게 많은거야?? 왜 하필!!



ES5와 ES6가 중요한 이유

본인이 JS를 공부하기 위해 쓰는 코어 자바스크립트라는 책에서도 항상 나오는 것이 ES6에 대한 이야기이다. 아마 다른 기본서들도 이 버전에 대한 이야기가 많을 것이라고 생각한다.

이 이유는 ES6에서 추가된 문법들이 기존의 문제들을 매우 깔끔하게 해결하게 해주었으며, 가독성 및 유지 보수성을 보강하는 문법도 추가 되었다.

JSX에 대해 설명할때, babel에 대한 이야기가 있었다.

다시 한번 상기 시키면, babel은 최신코드를 이전코드로 바꾸어서 모든 브라우저에서 이를 읽기 쉽게 하는 것이 목표이다. babel 덕분에 ES6의 최신 문법을 사용하면서 ES5를 따르는 문법으로 알아서 바뀌게 할 수 있었고, 호환성 문제도 해결이 되었다.

→ 이게 왜 중요하냐면, JS에 버전이 업그레이드 될수록, 웹 브라우저가 못따라는 경우가 있다. 예시로 IE 같은 경우에는 ES6을 못따라왔다. 근데 이렇게 된다면 표준을 정한 의미가 사라지는 것이다. 모든 브라우저에서 이해할 수 있게 하기 위해 JS표준을 정한건데, 어떤 브라우저는 사용을 못한다? 심각한 문제인것이다. 이를 babel 이 해결해주었다.

babel에 대해 이해가 어렵다면 아래 주소의 Babel이란? 부분을 참고해보자

https://velog.io/@sean2337/Front-End-JSX%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80



ES6에 뭐가 추가 되었길래??

→ 문법들이 너무 많아서 추가된 문법중에 본인이 중요하다고 생각하는 문법 7가지만 소개하겠다.

1. 트랜스 파일러(babel)를 사용한 크로스 브라우징 지원

이 기능은 앞에서 했던 babel 이야기와 동일하다. 예시로 ES6에는 템플릿 리터럴(Template literal) 기능이 추가되었는데, 이를 babel 을 통해서 ES5 코드로 변화시켜준다.

  • 예시코드
//ES6
cosole.log('Hello,${person.name}');
//ES5
cosole.log("Hey, " + person.name);

→ 위에 코드가 ES6인데, 이를 IE에서 실행시킨다면 오류가 뜰 것이다. 하지만 babel 덕분에 위에 코드를 치면 아래 코드로 알아서 변환시켜준다. 이를 통해 호환성 문제를 해결했다. 아래 기능이 이루어지는건 모두 이 덕분이라고 할 수 있다.


2. 변수 선언 방법 → let, const 추가

이전 버전인 ES5는 var 키워드만 사용했다. var은 언제나 변수의 값을 변경할 수 있었다. 개발에 있어서 변수에 제한을 두지 않는다는 것은 매우 치명적이다. 또한 hoisting 문제가 발생한다.

hoisting?
JS는 함수가 실행 되기전 함수에 필요한 변수를 모두 모아서 유효 범위의 최상단에 선언하는 기능이 있는데, 이를 hoisting 라고 한다.
쉽게 말해, 함수 실행전에 함수를 한번 쭉~ 훑고, 함수 안에 필요한 변수, 함수에 대한 정보를 기억해두고, 이를 맨위로 끌어올린다. 아래와 같은 코드가 있다고 가정해보자.

- hoisting 전

```html
cosole.log("check");
var myName = "sean";
let yourName = "Joo";
```

- hoisting 후

```html
var myName; -> 최상단으로 이동
cosole.log("check");
myName = "sean";
let yourName = "Joo";
```

이렇게 된다면 원하지 않는 구간에 hoisting때문에 최상단으로 이동한 변수에 대한 데이터 값을 건들어 버릴 수도 있는 노릇이다.

이러한 문제들을 해결하기 위해 let, const를 개발했다.

var 같은 경우, 해당 스코프 밖에서도 이를 건들수도 있지만, let, const 는 해당 스코프 밖에서 이를 건들면, Reference Error 를 발생시킨다.

그리고 let, const 의 차이는 변수의 값들이 변할 수 있는가(let ), 없는가(const)로 구분된다.

이런식으로 변수 선언에 여러가지를 두면서, 개발자들에게 변수에 대한 제한을 두게 해주었다.


3. Arrow function (화살표 함수)

Arrow function 덕분에 this 바인딩 문제를 해결해주었고, 함수 표현식을 단축시켰다.

화살표 함수는 말그대로 함수 표현식에서 => 이를 사용하는데 이것이 화살표와 유사하여, 화살표 함수라는 말을 붙였다. 대부분이 이를 써봤을 것이다.

이에 대한 장점을 알려면 this 바인딩 에 대해 알아야한다.

this 바인딩? (간단하게)

this는 문맥상 어디에 있냐에 따라 값이 바뀐다. 이때, this가 계속 바뀌는 것을 막기 위해 값을 고정시킬때가 있는데 이를 말한다.

따라서this 바인딩 을 간단하게 말해보면, this에 대한것을 고정시키는 것을 말한다.

이것을 Arrow function으로 해결가능하다.

화살표 함수는 this를 사용시 this의 값은 바로 상위 코드의 값으로 고정이 된다. 이 말이 무슨 말인지 이해가 안간다면, 코드를 통해 봐보자.

 const account = {
  username: "시현",
  money: 10000,
  getMoney: function() {
    innerFunc = () => `${this.username}님의 잔고는 ${this.balance}입니다.`;
    console.log(innerFunc());
  }
};
account.getBalance(); // 시현님의 잔고는 10000원입니다.

innerFunc()에 있는 this는 바로 상위 코드에 있는 username, getMoney 가 있는 쪽을 가리킨다. 한마디로 this 부분을 감싸고 있는 부분을 가리키게 된다.

그렇다면 이걸 안쓴다면?

const account = {
  name: "시현",
  hello: function () {
    console.log(`hi ${this.name}`);
  },
};

account.hello(); // hi undifined

화살표 함수를 쓰지 않는다면, 이렇게 지정해주어야 한다. 지정해주면, 지정해준 객체를 가리키게 된다.

이게 왜 문제야? 할 수 있는데 바로 이벤트 핸들러 함수 를 사용할때 이 때문에 의도하지 않은 문제가 발생한다.

var buzzer = {
  name: 'Buzzer1',
  addClickEvent: function() {
    this.element = document.getElementById(this.name);

    var logNameAndRemoveButton = function() {
      console.log(this.name + ' buzzing!');
    }

    this.element.addEventListener('click', logNameAndRemoveButton.bind(this)); 
// logNameAndRemoveButton 핸들러 함수 실행시 this 객체가 엘리먼트 객체 이므로 
// "bind(this)"를 이용해서 this객체를 지정해준다.
  }
};

buzzer.addClickEvent();

위에 코드는 ES5 기준으로 짠 코드이다. 여기서 중요한 것은 bind(this) 를 씀으로써 this를 지정해주었다는 것이다. ES6이 나오기 전에는 이벤트 처리를 할때, 내부에서 사용할 this를 바인딩 시켜서 넘겨주는 과정이 필요했다.

→ 함수 내부에서 this를 쓸때는 그 함수 밖에서 쓸 this를 입력해주는 바인딩 과정이 필요했음.

매우 귀찮은 일이다……

자 그렇다면 ES6으로 하면 어떨까?

const buzzer = {
  name: 'Buzzer1',
  addClickEvent() {
    this.element = document.getElementById(this.name);

    this.element.addEventListener('click', () => {  
		// buzzerElement에 다시 this 바인드를 하지 않아도 의도한 대로 실행된다.
      console.log(this.name + ' buzzing!');
      document.body.removeChild(this.element);
    });
  }
};

buzzer.addClickEvent();

→ 바인딩 과정 없이 그냥 this를 쓰는 것만으로 알아서 실행된다. 이것이 매우 큰 장점으로 작용한다.

물론 this를 감싸고 있는 부분을 가리킨다는 점은 안좋은 점으로 작용할 수도 있다. this를 지정해주어야 하는 상황도 있을 것이다.

하지만 이 Arrow Function은 우리가 자주쓰는 이벤트 핸들러 함수에서 매우 좋게 작용하기 때문에 큰 장점이라고 할 수 있다.


4. 클래스

JS에는 원래 클래스 기반 언어가 아니라서, 클래스란게 존재하지 않았다.

ES6이 나오기 전엔 클래스 사용을 위해, 클래스를 구현한 API를 사용하였다. 이렇다보니, 라이브러리가 통일되지 않아서, 클래스 쓰는 방법들이 라이브러리 마다 달랐다.

ES6에는 클래스 문법이 등장했고, 이전에 있던 통일 문제를 해결했다.

이번 글에서는 클래스 사용에는 깊게 다루진 않겠다. 아래 예시코드 느낌으로 짜는거구나 맛만 보자

class TestClass {
  static staticClassMethod() {
    // 정적 메서드
  }

  constructor() {
    // 생성자 함수
  }
  
  testMethod() {
    // 클래스 매서드
  }
}

const test = new testClass(); 
instance.testMethod();

5. 객체 리터럴에 개선(Object)

ES5에선 아래와 같이 코드를 만들었어야 했다.

var name = "sean";
var age = "23";
var job = "student";

var human = {
  name: name,
  age: age,
  job: job,
};

human이라는 객체 리터럴을 만들때, 새 객체에 변수명과 같은 프로퍼티 키를 만들고 변수의 값을 프로퍼티의 값으로 대입을 해줘야 했다. 이게 무슨….. 지금 본인으로써는 상상도 못하는 일이다.

그렇다면 ES6은 어떨까?

var name = "sean";
var age = "23";
var job = "student";

var human = {
  name,
  age,
  job,
};

→ 새로운 프로퍼티 키를 만들지 않아도 그냥 대입만 하면 알아서 객체 리터럴을 만들어준다. 좀 더 사용자에 대한 편의를 봐준 케이스이다.


6. 템플릿 리터럴(Template literal)

우리는 개발을 할때 $ 이걸 많이 써봤을 것이다. 예를 들어

var name = "sean";
var age = 23;
var answer = `안녕하세요 ${name} 당신은 ${age}살이시군요!!`;

console.log(answer);

ES6이전엔 이게 불가능했다. 그렇다면 어떻게 코드를 짰어야 했을까?

var name = "sean";
var age = 23;

var answer = "안녕하세요 " + name + " 당신은 " + age + "살이시군요!!";
console.log(answer);

문자열을 더해서 새로운 문자열을 만들었어야 했다… 너무 비효율적이다. 이게 맞아?

대신에 ES6부터 백틱 으로 문자열을 감싸면서 그 사이에 ${표현식} 이 가능해졌다.


7. 모듈

우리가 React를 사용하다 보면 import, export 를 많이 사용해본 경험이 있을것이다. 이것은 원래부터 가능했던 것이 아니라 ES6부터 가능한 일이였다.

export를 통해서 모듈을 만들어놓고 다른 파일로 보낼 수 있어졌다.

ES6 이전에는 이것이 불가능하여, 모듈을 개발하더라도 이를 웹 브라우저 에서 실행할 수 있도록 바꿔주는 별도의 작업(Webpack, Rollup 등등) 이 필요했다.



정리

지금까지 ES6의 새로운 기능에 대해 말해보았다. 사실 이것이 끝이 아니다. 새로 추가된 기능은 저것보다 훨씬 많다.

ES5에서 ES6으로 넘어가면서 앞서, 설명한 이전에 있었던 문제나 사용자의 편의를 매우 상승시키는 업데이트들이 많았다. 본인이 설명한 일곱까지만 해도 우리가 당연시 쓰고 있던 것들이며, 이것이 없다면 매우 불편함을 겪었을 것이다.

사람들이 ES5에서 ES6을 계속적으로 언급하는 이유는 이때 엄청난 변화(위에 언급한 것 + 추가)가 많았기 떄문이라고 생각한다. ES5 -> EC6으로 이동하면서 혁명적으로 많은 것들이 한번에 발전했다. 원래는 ES가 1년에 한번씩은 업데이트 되곤 하는데, 이때는 6년이라는 긴 시간 동안 많은 부분에서 발전했다. 다른 업데이트 들은 조금씩 바뀌었다면, 이 부분에서 많은 것들이 훨씬 효율적으로 변하고, 추가 되었다.
이 덕분에 지금의 JS가 있을 수 있었고, React가 있을 수 있었다고 생각한다.
그래서 사람들이 ES5, ES6에 대한 언급이 많은 것이라고 생각한다.

마치 나 때는 이런거 없었는데.... 요런 느낌??

좀 더 궁금한 사람을 위해, ES6의 추가된 기능을 모두 정리한 사이트를 공유하려한다. 뭐가 더 바뀌었는지 궁금한 사람은 아래 링크를 참고하길 바란다. (대부분 중요한 내용은 위에 7가지임)



참조

  1. https://doozi0316.tistory.com/entry/JavaScript-ECMAScript%EB%9E%80-ES5%EC%99%80-ES6%EC%9D%98-%EC%B0%A8%EC%9D%B4var-const-let-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98-class
  2. https://sumini.dev/til/006-ecmascript/
  3. https://webroadcast.tistory.com/14
  4. https://bohyeon-n.github.io/deploy/javascript/this.html
profile
집돌이 FE개발자의 노트

0개의 댓글