본문 바로가기
Javascript

ES6, ECMAScript 6 의 새로운 것. 자바스크립트2015(javascript 2015)

by 램쥐뱅 2017. 6. 20.

자바스크립트 2015는 ECMAScript 6 또는 ES6 이라고도 하며, 자바스크립트 언어의 새로운 버전이다.

ES6에는 클래스, 모듈, 새로운 변수 선언 키워드와 프로미스를 비롯해 복잡한 애플리케이션을 작성하기 위한 새로운 구문이 많이 추가되었다. 또한 좀더 간결해진 함수 표기법, 템플릿 문자열, 구조 분해와 같이 코드의 표현력을 높이기 위한 새로운 편의 문법(syntactic sugar) 기능도 추가됐다.




클래스


자바스크립트 class는 ES6에 추가됐으며 자바스크립트의 기존 프로토타입 기반 상속에 기반을 두는 편의 문법이다.

클래스 구문이 자바스크립트에 새로운 객체 지향 상속을 추가하는 것은 아니지만 훨씬 간단하고 알아보기 쉬운 자바스크립트 클래스 구분으로 객체를 생성하고 상속을 처리할 수 있다.


클래스는 프로토타입 기반 상속, 상위 호출, 인스턴스와 정적 메서드, 생성자를 지원한다.


class Point {

constructor(x, y) {

this.x = x;

this.y = y;

}


toString() {

return `(${this.x}, ${this.y})` ;

}

}


class Pixel extends Point {

constructor(x, y, color) {

super(x, y);

this.color = color;

}


toString() {

return super.toString() + ' in '+this.color;

}

}


기존 자바스크립트로 간략하게 다시 바꿔 본다면.


function Point(x, y){

this.x = x;

this.y = y;

}


Point.prototype.toString = function(){

return '('+this.x+','+this.y+')';

}


function Pixel(x, y, color){

Point.call(this, x, y);

this.color = color;

}


Pixel.prototype = new Point();

Pixel.prototype.toString = function(){

return Object.getPrototypeOf(Pixel.prototype).toString.call(this)+' in '+this.color;

}


정도로 볼 수 있을것 같다.


const p = new Pixel(25, 8, 'green');

p.toString(); // (25, 8) in green


내부를 들여다보면 ES6 클래스는 완전히 새로운 것이라기 보다 기존의 생성자 함수를 작성하는 좀 더 편리한 구문이라고 할 수 있다.

typeof 로 이를 확인할 수 있다.


 typeof Point // 'function'




모듈


모듈은 모든 프로그래밍 언어에서 가장 중요한 기능이며, ES6에서는 일급 시민이 됐다.

ES6모듈은 자바스크립트 코드를 포함하는 파일이다. 특수한 모듈 키워드는 따로 없으며 exprot 키워드가 추가되지만 일반적인 스크립트와 거의 동일하다.



익스포트


기본적으로 모듈 안에서 선언된 모든 사항은 해당 모듈에 대해 로컬이다.

모듈안에서 선언한 항목을 공용으로 선언하고 다른 모듈에서 사용할 수 있게 하려면 export를 이용해 해당 항목을 익스포트해야 한다.


function generateRandom() {

return Math.random();

}


function sum(a, b) {

return a + b;

}


export { generateRandom, sum };


최상위 함수, 클래스, var, let, const 를 익스포트할 수 있다.



임포트


import 문은 외부 모듈, 다른 스크립트 등에서 익스포트한 함수, 객체, 기본형을 임포트하는데 사용된다.


import { generateRandom, sum } from 'utility'; // from '{export 한 모듈이 존재하는 확장자를 제외한 js 경로} '


console.log(generateRandom()); // 임의의 수 console 출력

console.log(sum(1, 2)) // 3



기본 익스포트 


기본 익스포트를 사용해 모듈에서 단일 값을 익스포트할 수 있다.


var utils = {

generateRandom : function() {

return Math.random();

},

sum : function() {

return a + b;

}

};


export default utils;


임포트할 때는 기본 익스포트의 이름을 지정하면 된다.


import utils from 'utility' // default export 된 모듈을 import 할때는 {} 제외가능


console.log(utils.generateRandom()); // 임의수 수 console 출력

console.log(utils.sum(1, 2)) // 3




let 과 const


javascript var 선언은 다음 에제 코드에서 볼 수 있듯이 함수 내에서의 변수 스코프를 가지고 있는 잠재적 위험성을 안고 있다.

자바스크립트 변수 스코프의 특징이다. 참고 : http://jusungpark.tistory.com/32 


function foo() {

var myVariable = "10";

}


foo();

console.log(myVariable) // undefined


if(false) {

var myVariable = "10";

}


console.log(myVariable) // 10 (myVariable 변수는 "if" 블록 범위에 속하지 않고 전역 스코프를 갖는다. web환경이면 window에 가짐)



let


ES6에서는 변수를 선언하는 새로운 두 키워드인 letconst가 추가됐다. 두 구조는 모두 블록 스코프를 갖는 바인딩 구조라고 할 수 있으며, let은 개선된 var라고 생각할 수 있다.


if(true){

let myVariable = "10"';

}


console.log(myVariable) // undefined (myVariable 변수는 "if" 블록 스코프를 가진다)


var를 사용할 수 있는 곳에는 let을 사용하는 것이 일반적으로 안전하다.



const


const 선언은 단일 값 할당을 위한 선언으로서 값에 대한 읽기 전용 참조를 만든다.

책과 몇몇 글에 const는 포함된 값이 변경 불가가 되는 것은 아니며 변수 식별자를 다시 할당할 수 없다는 의미라고 하는데 예제와 설명이 달라 헷갈리게 만든다. 내가 내린결론은 const는 자바의 final 처럼 변수의 내용을 변경할 수도 없고, 식별자를 다시 할당할 수도 없다. 더 자세한 내용은 링크 참고 (https://hyunseob.github.io/2016/11/21/misunderstanding-about-const/)


const MY_FAV = 7;

MY_FAV = 20; // "상수에 값 할당" Error

let MY_FAV; // "Error"


const MY_FUNC = function(a, b){

return a > b ? true : false;

}




화살표 함수


화살표는 => 구문을 이용하는 함수 단축 표기법이다. 화살표 함수는 구문을 간결하게 하고 부모 스코프와 렉시컬(lexical) this를 공유하는 두 가지 용도로 사용된다.


간결한 구문


기존 자바스크립트 함수 구문은 함수가 문 하나를 포함 하느냐 여러 페이지를 포함 하느냐와 상관없이 유연성을 제공하지 않는다.

즉, 함수가 필요할 때마다 귀찮은 function() { } 구문을 모두 타이핑 해야 한다. 화살표 함수의 가장 큰 장점은 간결한 구문을 사용할 수 있다는 것이다.


setInterval(function(){   // old

console.log("Time is passing")

}, 1000);

// 간단한 예

setInterval(() => console.log("Time is passing"), 1000);


let square_old = function(num){

return num*num;

}

// 한 행 함수(암시적 반환)

let square = (num) => num * num;

console.log(square(5)) // 25


var nums = [1,2,3,4,5];

nums.forEach(function(v){   // old

 console.log(v)

});

// 여러 행

nums.forEach(v => {

 console.log(v)

});


let actors = ['Adam West','Michael Keaton','Val Kilmer','George Clonney','Christian Bale','Ben Affleck'];

actors.map(function(actors){    // old

return actors + 'is Batman!\n';

});

// 여러 행 함수(암시적 반환)

actors.map((actor)=>(

actor + ' is Batman!\n'

));



렉시컬 바인딩


자바스크립트의 모든 함수는 자체 this 컨텍스트를 정의하는데, 우회하시는 어렵지 않지만 귀찮은 것이 사실이다. 화살표 함수는 this의 값을 선언된 위치에서 부모 스코프와 렉시컬 바인딩(또는 정적 바인딩) 한다.


var val = "Window val";

function ScopTest(){

this.val = "Scop Test val";

return function(){

console.log(this.val); //this 는 ?

}

}


var val = "Window val";

function ScopTest(){

this.val = "Scop Test val";

return () => {

console.log(this.val); //this 는 ?

}

}


var bob = {

name : "bob",

friends : ["a","b","c"],

printFriends() {
    this.friends.forEach(data => { // printFriends function 하위 this 는 bob 과 같은 this

        console.log(data);

    });

}




프로미스


프로미스는 비동기 프로그래밍을 위한 라이브러리이며, 미래에 사용 가능할 수 있는 값에 대한 일급 표현이다.

프로미스는 여러 기존 자바스크립트 라이브러리에 사용된다. (비동기 완료 시점 중첩 콜백대신 Promise 패턴 사용 ) 제이쿼리를 사용하면서도 사용해봤을 것이다.


function timeout(duration = 0){

return new Promise((resolve, reject) => {

setTimeout(resolve, duration);

});

}


var p = timeout(1000).then(() => {

return timeout(2000);

}).then(() => {

throw new Error("hmm");

}).catch(err => {

return Promise.all([timeout(100), timeout(200)]);

});




템플릿 문자열


자바스크립트의 문자열은 파이썬이나 루비 등의 다른 언어에 비해 제한적이고 기능도 부족하다. ES6의 템플릿 문자열은 편의 문법을 활용해 문자열을 구성하는 방법으로 기존 문자열의 한게를 근본적으로 해결했다.



구문


템플릿 문자열은 일반 문자열의 '(apostrophe)나 "(quotation mark)큰따옴표 대신 `(backtick)을 이용한다.


var greeting = `To World!`;



문자열 대체


템플릿 문자열의 첫 번째 기능은 문자열 대체다. 유요한 자바스크립트 식(예: 변수의 합)을 템플릿 리터럴 안에 지정하면 동일한 문자열의 일부로 결과가 출력된다.


var name = "Brendan";

console.log(`To, ${name}!`); // "Yo, Brendan!"



다중 행 문자열


자바스크립트에서 다중 행 문자열을 지정 하려면 다소 엉성한 방법에 의존해야 한다.


console.log('string text line1\

string text line2\

string text line3');


템플릿 문자열을 이용하면 아주 간단하게 다중 행 문자열을 지정할 수 있다. 간단하게 문자열 중간에 줄바꿈을 넣으면 된다.


console.log(`string text line1

string text line2

string text line3`);




구조분해 할당


구조분해 할당 구문은 배열이나 객체의 데이터를 여러 변수로 추출할 수 있는 자바스크립트 식이다.


// 배열 비교

var a, b, rest;

[a, b] = [1, 2];

console.log(a) // 1

console.log(b) // 2


// 객체 비교

var robotA = { name : "Bender" };

var robotB = { name : "Flexo" };


var { name : nameA } = robotA;

var { name : nameB } = robotB;


console.log(nameA); // "Bender"

console.log(nameB); // "Flexo"


// 매개변수 위치에 사용할 수 있음

function g( {name : x} ) {

console.log(x);

}

g( {name : "A"} ); // "A"




기본 매개변수


ES6는 function의 매개변수에 기본값을 지정해줄 수 있다.


// 적용 전

function multiply(a, b){

b = b ? b : 1; // 올바른 값의 파라미터 또는 파라미터 가 넘어오지 않았을 경우에 대해 따로 처리를 해주어야 했음.

return a * b;  

}


// 적용 후

function multiply(a, b=1) { // 넘어온 매개변수에 별 다른 값이 없으면 default value 인 1을 사용

return a*b;

}












참고.


프로 리액트 - React.js를 이용한 모던 프런트엔드 구축.

댓글