티스토리 뷰

ES6 in depth 요약글입니다.

ES6 in depth을 참고하여 공부겸 정리하였습니다.

ES6? ECMAScript가 도대체 무엇이지?

ECMAScript는 자바스크립트 표준 단체인 ECMA가 제정하는 자바스크립트 표준이다.
ECMAScript는 브라우저에 사용되는 자바스크립트 부분만 표준으로 정의한다.
우리가 현재 사용하고있는 자바스크립트는 ES5이며, 이전에는 ES1 ~ ES3까지 존재하고있다.

ES4는 논쟁요소가 많아 폐기 되었으며 ES5부터 먼저 제정하였다고함

let과 const

기존에 자바스크립트에서는 var를 이용하여 변수를 선언했다.

다른 프로그래밍 언어는 보통 블럭단위(block-level) 유효범위를 가지고있지만

이 var는 함수에 대해서만 Scope를 가지고있음


여기서 Sscope란 범위, 영역이란 뜻으로 쉽게 생각하면 변수의 유효범위다.

즉 함수를 경계로 변수의 영역이 나뉘어져있다.

Scope에 대한 내용은 해당 포스트 참고


그래서 ES6에서는 새로운 키워드인 let을 추가하였다.


let의 특징


- let은 블록단위 scope를 가진다.

- 글로벌 let변수는 글로벌 객체의 속성이 아님(window.x 가 아님)

- for문 등의 루프에서 for ( let v...) 구문에서 v는 루프마다 새로 바인딩함

- let은 선언 전부터 참조하면 에러

- 같은 let 변수 선언시 문법에러( 해결방법은 ES6의 모듈을 사용하는 것)


const의 특징


- let과 동일하나 다른점은 최초 값 할당 이후 값 변경이 불가능함(변하지 않는 값을 사용시에는 const를 이용하라) 변경하면 문법에러(SyntaxError) 발생

Arrow Functions(화살표)

ES6에서는 람다식 표현식 더욱 간결하게 해주는 Arrow 문법이 추가되었다. =>

실수로 비교연산자['<='  '>=']를 가끔 '=>' 로 쓰는 사람들이 가끔 있는데 앞으로는 더욱 주의해야 할지도 모르겠다.

// ES5
var selected = allJobs.filter(function (job) {
  return job.isSelected();
});
// ES6
var selected = allJobs.filter(job => job.isSelected());

// ES5
var total = values.reduce(function (a, b) {
  return a + b;
}, 0);

// ES6
var total = values.reduce((a, b) => a + b, 0);

{}이 객체인지 블럭구문인지 구분이 안된다. 그래서 객체인 경우는 아래와 같이 사용해주자

var chewToys = puppies.map(puppy => {}); // Error var chewToys = puppies.map(puppy => ({})); // 객체로 인식

javascript 프로그래밍시 가장 많이 쓰이던 구문인 var self = this; 이제는 그럴 필요가 없어진다.

//ES5
{
  ...
  addAll: function addAll(pieces) {
    var self = this;
    _.each(pieces, function (piece) {
      self.add(piece);
    });
  },
  ...
}

// ES6
{
  ...
  addAll: function addAll(pieces) {
    _.each(pieces, piece => this.add(piece));
  },
  ...
}

// ES6 with method syntax
{
  ...
  addAll(pieces) {
    _.each(pieces, piece => this.add(piece));
  },
  ...
}

for /  for in 그리고 for of

기존에 사용하던 루프문인 for문

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}


ES5에 추가 되었던 forEach문

myArray.forEach(function (value) {
  console.log(value);
});


forEach의 단점은 return 혹은 break를 통한 루프 탈출이 불가능하다는 점이다.

루프 제어면에서는 for문이 훨씬 좋다.


마찬가지로 ES5에 추가 되었던 for in 구문을 보자

for (var index in myArray) {
  console.log(myArray[index]);
}

for in문의 경우 나쁜점이 몇가지 있다고하는데(사실 나쁜점이 아니라 for in 구문 자체가 object를 루프 돌기 위해 나온 구문이다.)


1.myArray의 prototype chain도 순회한다.

1.순서가 무작위이다.

1.var index 값이 string이다.


정리: 배열을 컨트롤하는 구문이 아니라 object를 컨트롤 하기 위한 구문이다.


그래서 ES6에서는 for of 구문이 등장하였다.


사실 여기서 느꼈던 점은 ECMAScript가 새로 개정되면 기존 소스를 못쓰는거 아니야?!

이런 생각이 나기 마련인데 ECMAScript에서는 기존 소스가 실행이 안되는걸 원치 않는다고 한다.

그래서 기존 루프문을 수정하는게 아닌 새로운 구문을 추가하는 형식으로 진행하는것 같다.


for of문을 살펴보자

for (var value of myArray) {
  console.log(value);
}

for in 구문과 모양새가 똑같다.


하지만 forEach와 다르게 breck / continue / return 등을 통하여 루프 제어가 가능하다.

for in 과 다르게 배열의 데이터를 컨트롤 하기 위한 루프문이다.

(순서대로 돌며 배열 요소들만 루프에 포함된다)


정리: 배열(array)은 for of / 객체(object)는 for in


Class(클래스)

기존의 자바스크립트에서의 클래스 구현은 직관적이지 않았으며 클래스 생성을 위해 함수에 동작에 대해 자세히 알아야했다.
이런점을 개선하고자 Class 문법이 추가되었다.

Class는 hoisting(호이스팅)이 지원안되니 참고!!

class Circle {
    constructor(radius) {
        this.radius = radius;
        Circle.circlesMade++;
    };

    static draw(circle, canvas) {
        // Canvas drawing code
    };

    static get circlesMade() {
        return !this._count ? 0 : this._count;
    };
    static set circlesMade(val) {
        this._count = val;
    };

    area() {
        return Math.pow(this.radius, 2) * Math.PI;
    };

    get radius() {
        return this._radius;
    };
    set radius(radius) {
        if (!Number.isInteger(radius))
            throw new Error("Circle radius must be an integer.");
        this._radius = radius;
    };
}

SubClass(서브클래스)

ES6에서는 클래스 상속(Inheritance)도 지원한다.


class Shape {
    constructor(color) {
        this._color = color;
    }
}

class Circle extends Shape {
    constructor(color, radius) {
        super(color);

        this.radius = radius;
    }

    // As from above
}

iterator(이터레이터) 와 iterable(이터러블)


이터레이터와 이터러블은 다른 프로그래밍 언어에서도 구현되어있는 개념인데
ES6에서는 뒤에 설명할 Generator(제너레이터)를 위해 설명하는 경우가 많다.

ES6부터는 .next() 메서드를 이용하여 객체안의 정보들을 순차적으로 접근할 수 있는 iterator object를 제공한다.
아래는 기본적으로 iterator object 구현 방법이다.

var Iter = {
  [Symbol.iterator]: function() {
    return this;
  },
  next: function() {
    return { done: false, value: 0 } 
  }
}

결과는 계속 0을 리턴하며 무한루프를 돌게된다. 이렇게 객체에 Symbol.iterator() 메서드를 추가하면 for of문을 이용하여 객체를 

순회 할 수 있는 객체를 iterator object라고 한다.


그럼 iterable은 무엇인가? 멤버들을 하나씩 반환가능한 형태를 iterable라고 한다.

iterator === iterable 은 아니다 array는 iterator가 아니지만 iterable한 객체이다.

댓글