프로그래밍/JavaScript

ECMA SCript?란? (ES란?)

HP_Factory 2021. 1. 22. 08:00

ECMA Script(ES)?

자바스크립트는 1990년대 Netscape 회사의 Brendan Eich 라는 사람에 의해 최초 개발되었습니다. 자바스크립트가 잘 되자, MS에서 Jscript라는 언어를 개발해 IE에 탑재하였는데, 이 두 스크립트가 너무 제가각이라, 표준이 필요하게 되었습니다.

 

표준을 위해 자바스크립트를 ECMA(European Computer Manufactures Association)라는 정보와 통신시스템의 비영리 표준 기구에 제출하였고 표준에 대한 작업을 ECMA-262란 이름으로 1996년 11월에 시작해 1997년 6월에 채택되었습니다.

 

ECMA가 다루는 표준(출처 : 위키)

종종 보게되는 ES란 ECMA Script의 약자입니다. ES5는 ECMA Script5의 규격을 따른다고 생각하면 됩니다.

 

 

JavaScript와 ECMA Script

둘 다 뒤에 Script라는 키워드가 붙지만, 자바스크립트는 언어이고, ECMA 스크립트는 규격, 표준 즉, 스펙을 말합니다.

 

ES 버전에 따른 특징

ES는 최초 표준이 정의된 이후, 세월과 함께 발전해왔습니다. 각 버전에 따라 어떤 특징들이 있는지 정리해보겠습니다.

 

  • ES3(1999)
    우리가 흔히 말하는 자바스크립트 입니다. 함수 단위의 스코프, 호이스팅, 모듈화 미지원, 프로토타입, 클로저 등등 자바스크립트의 기본적인 특징들이 들어있습니다. 

    대부분의 브라우저에서 지원하고, IE8까지 크로스브라우징하는 환경이면 ES3를 쓰고 있다고 생각하면 됩니다.

  • ES5(2009)
    4는 너무 급변하는 내용이 있었던지 거절되고, 그 후에 점진적인 개선을 하고자 5가 나왔습니다. 기본적으로 IE9부터 본격적으로 지원을 하지만 es5-shim을 사용하면 하위 버전에서도 특정 기능들을 지원해줍니다.

    5부터 추가된 기능으로는 다음과 같습니다.

    1. 배열과 관련해서 새로운 메소드들이 생겼는데 대표적으로 forEach, map, filter, reduce, some, every와 같은 메소드가 생겼습니다. 이 메소드들은 개발자가 반복 횟수나 조건을 잘못 입력하는 등의 실수를 줄여주는 효과가 있습니다.
    2. object에 대한 getter/setter 지원
    3. 자바스크립트 strict 모드 지원(더욱 세심하게 문법 검사를 합니다.)
    4. JSON 지원(과거에는 XML을 사용하다가, json이 뜨면서 지원하게 되었습니다.)
    5. bind() 메소드가 생겼습니다. (this를 강제로 bind 시켜주는 메소드입니다.)

  • ES 2015(ES6)
    원래는 ES6 였는데 사람들이 끝자리인 6과 2016년을 연관짓는 습성 때문에 2016년에 나온걸로 착각을 해서인지 ES2015로 바꾼 것 같습니다.....

추가된 기능으로는 다음과 같습니다.

1. let, const 키워드 추가
기존의 변수는 함수 scope를 가진 var 키워드를 이용하여 선언하였습니다. 때문에 block scope를 가진 let과 const 키워드를 추가하였습니다. 기존에는 상수형 키워드가 없어 CONST_TEST와 같이 대문자로 상수임을 표시했다면, ES 6부터 const 키워드가 추가되어 값의 변경을 통제합니다.

2. arrow 문법 지원

arrow 문법은 두 가지의 장점을 제공합니다. 첫 번째는 익숙하면 편하고 간결해진 코드를 작성할 수 있습니다. 두 번째는 this를 바인딩하지 않습니다.(다르게 말하면, this는 해당 scope의 this와 같습니다.)

 

두 번째 this를 바인딩 하지 않는다는 코드로 설명하겠습니다. 우선 아래 코드를 보면, test 객체에 name 변수와 fn이라는 메소드를 두었습니다. 아래 test.fun으로 메소드를 실행합니다.

 

기대했던 결과는 다음과 같습니다.

sjk want buy computer
sjk want buy notebook

 

하지만, 결과는 아래와 같았습니다.

ReferenceError: name is not defined

name 변수를 인지하지 못하는건가??? this.name으로 바꿔볼까? 7번 line의 name을 this.name으로 변경했습니다.

결과는 아래와 같습니다.

undefined want buy computer
undefined want buy notebook

 

this가 뭘 참조하고 있는거지?? 위 코드의 7번 line의 this.name을 this로 변경하여 출력하면 아래와 같습니다.

[object global] want buy computer
[object global] want buy notebook

 

그러니까, this가 전역 객체를 자동으로 바인딩 하고 있는 문제가 있습니다.
언제부터?? 다음 코드를 실행해보면 forEach 함수 호출전에 this를 출력하고 있습니다.

 

결과는 아래와 같습니다. 그러니까 fn 메소드 내부에서는 this가 유지되는데, fn 메소드 내부의 다른 함수 내부 영역에서는 this가 전역 객체를 자동으로 바인딩하고 있습니다.

 

{ name: ‘sjk’, fn: [Function: fn] }
[object global] want buy computer
[object global] want buy notebook

 

보통 이 문제를 해결하기 위해 5번의 line의 this를 변수에 저장하고 다음과 같이 쓸 수 있습니다.

즉, arrow 문법의 두 번째 장점 this를 바인딩하지 않는다는 걸 알게 되었고(this를 동적으로 바인딩하지 않는다는 말과 같습니다.), arrow 문법을 쓰게 되면 this를 바인딩 하지 않고 선언된 scope의 this를 가리킨다는 장점이 있다는 것을 확인해보았습니다.

 

3. iterator / generator 추가

4. module import / export 추가

5. Promise 도입 ( Callback Hell을 해결해 줄 기법이 추가 되었습니다.)

6. Default, Rest 파라미터

7. 해체 할당, Spread 연산자

8. 템플릿 리터럴

9. 호이스팅이 사라진 것 같은 효과

10. 함수 단위 스코프에서 블록 단위 스코프로 변경

 

  • ECMA 2017(ES8)
    async - await의 기능의 추가가 대표적으로 있습니다.

    - async - await
    위에서 ES6에서 Callback Hell을 해결하기 위해 Promise가 도입되었다고 했는데 async-await도 Promise처럼 Callback을 해결할 뿐만 아니라 좀 더 직관적이고 단순하게 코드를 만들 수 있습니다.


    간단히 설명하자면
    async function 함수명() {
        await 비동기_처리_메소드_명();
    }
    으로 이루어져 있고 먼저 함수의 앞에 async 라는 예약어를 붙입니다. 그러고 나서 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await을 붙입니다. 여기서 주의하셔야 할 점은 비동기 처리 메소드가 꼭 프로미스 객체를 반환해야 awiat가 의도한 대로 동작합니다.

    일반적으로 await의 대상이 되는 비동기 처리 코드는 Axios등 프로미스를 반환하는 API 호출 함수 입니다.

async - await 예제



ES6 화살표 함수

ES6 부터는 화살표 함수를 사용할 수 있게 되었습니다. 기존과의 차이점은 다음과 같습니다. (차이점의 예시는 함수의 선언 방식으로 예시를 들겠습니다.)

ES5
ES6
ES5
ES6

정리
var plus = function example (a,b) { return a+b; } 로 사용되던 것이
let plus = (a,b) => {return a+b} 처럼 간결하게 사용할 수 있게 되었습니다.

 

 

결론

ES의 대한 내용을 다루면서 저도 한번 더 알고 있던 개념을 정리하고 새로운 개념을 공부해보면서 새로운 특성도 알게되고 기존에 사용하던 패턴들을 다양화시켜 적용도 해보았습니다. 여러분들도 너무 어렵게 생각만 하지 마시고 ES에 대한 공부를 잘 하고 익숙해진다면 복잡하게 구현하던 것을 훨씬 간편하게 구현할 수 있게 될 것입니다.