ECMAScript 6(ES2015)

송재호·2021년 4월 9일
0

(먼저 알고 가기) Babel이란?

babel은 공식문서에 따르면 자바스크립트 컴파일러다.
인터프리터 언어에 컴파일러가 왜 필요한가?

babel은 소스 대 소스 컴파일러로, 상위 버전 script에서 작성된 소스를 하위 버전에서도 호환이 가능하도록 컴파일 해 준다.

*quick start vue.js의 저자는 ‘트랜스파일’과 ‘트랜스파일러’ 라는 용어를 사용했다.

참고 : babel 이란 무엇인가? (https://bravenamme.github.io/2020/02/12/what-is-babel/)

1. npm init (package.json 파일 생성)

2. npm install -g babel-cli yarn

3. yarn add -D babel-cli babel-preset-env babel-preset-stage-2 또는
npm install --save-dev babel-cli babel-preset-env babel-preset-stage-2

4. .babelrc 파일 생성 (babel 사용 위해 반드시 필요, 내가 직접 해야함)
{
	“presets” : [“env”, “stage-2”]
}

5. js파일 생성 및 작성 후 터미널에서 babel src -d build 하면 
build 폴더 밑에 트랜스파일된 스크립트 파일을 확인할 수 있음

let과 const

ES2015이전에는 변수 선언 위해 var 키워드 사용했다. var키워드는 호이스팅 때문에 복잡하며 중복 선언해도 문제가 발생하지 않았다. 또한 블록 단위 스코프를 지원하지 않고 함수 단위 스코프만 지원했다.

*호이스팅 : 실행 컨텍스트가 만들어진 후에 변수를 미리 생성

let

이러한 var의 문제점을 개선하여 나온 키워드가 let이다.
let은 블록 단위 스코프를 지원하며, 변수의 중복 선언을 방지할 수도 있다.

[ babel 트랜스파일 전 코드 ]

let msg = "GLOBAL";
function outer(a) {
	let msg = "OUTER";
	console.log(msg);
    	if (true) {
        	let msg = "BLOCK";
        	console.log(msg);
    	}
}

[ babel 트랜스파일 후 코드 ]

"use strict";

var msg = "GLOBAL";

function outer(a) {
    var msg = "OUTER";
    console.log(msg);
    if (true) {
        var _msg = "BLOCK";
        console.log(_msg);
    }
}

babel의 트랜스파일 결과를 보면, let의 블록 단위 스코프를 보장하기 위해 임의로 _를 붙여 새로운 변수명을 만들어 낸 것을 확인할 수 있다.

const

const는 상수 기능을 제공하는 용도다. 한 번 값이 주어지면 다시 변경할 수 없다.
const또한 블록 스코프를 지원한다.

기존 var는 변수의 중복 선언을 허용하지만, const와 let은 중복 선언을 허용하지 않는다.

기본 파라미터와 가변 파라미터

기본 파라미터

ES2015에서는 함수 파라미터의 기본값을 지정할 수 있다.

function addContact(name, mobile, 
                       home="없음", 
                       address="없음", 
                       email="없음") {
    var str = `name=${name}, mobile=${mobile}, home=${home}, 
               address=${address}, email=${email}`;
    console.log(str);
}

addContact("홍길동", "010-222-3331")
addContact("이몽룡", "010-222-3331", "02-3422-9900", "서울시");

가변 파라미터

ES2015에서는 여러 개의 파라미터 값을 배열로 받을 수 있다.

function foodReport(name, age, ...favoriteFoods) {
    console.log(name + ", " + age);
    console.log(favoriteFoods);
}

foodReport("이몽룡", 20, "짜장면", "냉면", "불고기");
foodReport("홍길동", 16, "초밥");

babel로 트랜스파일하면 전달하는 쪽의 인자가
[‘짜장면’, ‘냉면’, ‘불고기’] 와 같이 변환된 것을 확인할 수 있다.

구조분해 할당

구조분해 할당이란 배열,객체의 값들을 추출하여 여러 변수에 할당할 수 있는 기능이다.

let arr = [10,20,30,40];
let [a1,a2,a3] = arr;
console.log(a1, a2, a3); 	// 10 20 30

let p1 = {name:"홍길동", age:20, gender:"M"};
let { name:n, age:a, gender } = p1;
console.log(n,a,gender); 	// 홍길동 20 M

구조분해 할당은 함수의 파라미터에서도 사용 가능하다.

function addContact({name, phone, email="이메일 없음", age=0}) {
    console.log("이름 : " + name);
    console.log("전번 : " + phone);
    console.log("이메일 : " + email);
    console.log("나이 : " + age);
}
addContact({
    name : "이몽룡", 
    phone : "010-3434-8989"
})

화살표 함수

간결한 사용과 함수 정의한 영역의 this를 전달받기 위해 고안.
전통적인 자바스크립트의 this는 문맥에 따라 좌우되지만,
화살표 함수를 사용한 경우 this는 화살표 함수를 둘러싸고 있는 영역의 this를 그대로 따른다.

var test1 = function(a,b) {
	return a+b;
}
let test2 = (a,b) => {
	return a+b;
}
let test3 = (a,b) => a+b;

위 3개는 트랜스컴파일시 모두 동일한 코드로 작성된다.

새로운 객체 리터럴

ES2015에서는 객체의 속성을 작성할 때 변수명과 동일하다면 생략할 수 있다.

//기존 var obj = { name: name, age: age, email: email };
var obj = { name, age, email };

ES2015에서는 객체 내부 함수를 속성처럼 작성할 수 있다.
아래 예시에서 order는 기존 방식, discount는 ES2015 방식이다.

let p1 = {
    name : "아이패드",
    price : 200000,
    quantity : 2,
    order : function() {
        if (!this.amount) {
            this.amount = this.quantity * this.price;
        }         
        console.log("주문금액 : " + this.amount);
    },
    discount(rate) {
        if (rate > 0 && rate < 0.8) {
            this.amount = (1-rate) * this.price * this.quantity; 
        }
        console.log((100*rate) + "% 할인된 금액으로 구매합니다.");
    }
}

템플릿 리터럴

역따옴표 (``)로 묶여진 문자열에서 템플릿 대입문(${})을 이용해 동적으로 문자열을 끼워넣어 구성할 수 있다. 템플릿 대입문에는 수식 구문, 변수, 함수 호출 구문 등 대부분의 표현식을 사용할 수 있다. 또한 템플릿 문자열은 개행 문자를 포함하여 여러 줄로 작성이 가능하다.

var d1 = new Date();
var name = "홍길동";
var r1 = `${name} 님에게 ${d1.toDateString() }에 연락했다.`;
console.log(r1);

var product = "갤럭시S7";
var price = 199000;
var str = `${product}의 가격은
       ${price}원 입니다.`;

트랜스파일 된 코드를 살펴보면 개행문자가 포함된 문자열은
각 문자열을 이어붙이는 코드로 변경된 것을 확인할 수 있다.

컬렉션

ES2015는 Set, Map, WeakSet, WeakMap과 같은 집합, 맵을 제공한다.

Set

중복을 허용하지 않고 합집합(Union), 교집합(Intersect)과 같은 다양한 집합 연산자를 제공함.

var s1 = new Set();
s1.add("사과");   s1.add("배");
s1.add("사과");   s1.add("포도");
//실행 결과 : Set { '사과', '배', '포도' }
console.log(s1);

var john = new Set(["사과", "포도", "배"]);
var susan = new Set(["파인애플", "키위", "배"]);

//합집합 : Set { '사과', '포도', '배', '파인애플', '키위' }
var union = new Set([...john.values(), ...susan.values()]);
console.log(union);

//교집합 : Set { '배' }
var intersection = new Set([...john.values()].filter(e => susan.has(e)));
console.log(intersection);

//차집합 : Set { '사과', '포도' }
var diff = new Set([...john.values()].filter(e => !susan.has(e)));
console.log(diff);

map

키-값 쌍으로 이루어진 컬렉션이며 set(), get(), has(), claer(), delete() 등의 메서드를 제공

let teams = new Map();
teams.set('LG', '트윈스');     teams.set('삼성', '라이온스');
teams.set('NC', '다이노스');   teams.set('기아', '타이거스');
teams.set('한화', '이글즈');   teams.set('롯데', '자이언츠');

console.log(teams.has("SK"));       //false
console.log(teams.get("LG"));       //트윈스

클래스

기존 자바스크립트는 클래스가 제공되지 않아 함수를 이용해 유사 클래스를 만들어 사용했다. ES2015는 공식적으로 클래스를 지원한다.

class Person {
    constructor(name, tel, address) {
        this.name = name;
        this.tel = tel;
        this.address = address;
        if (Person.count) { Person.count++; } else { Person.count = 1; }    
    }
    static getPersonCount() { 
        return Person.count; 
    }
    toString() {
        return `name=${this.name}, tel=${this.tel}, address=${this.address}`;
    }
}

var p1 = new Person('이몽룡', '010-222-3332', '경기도');
var p2 = new Person('홍길동', '010-222-3333', '서울');
console.log(p1.toString());
console.log(Person.getPersonCount());

다른 언어의 클래스와 유사하게 정적 메서드, 인스턴스 메서드, 생성자를 지원하며 상속도 가능하다.

class Person {
    constructor(name, tel, address) {
        this.name = name;
        this.tel = tel;
        this.address = address;
        if (Person.count) { Person.count++; } else { Person.count = 1; }    
    }
    static getPersonCount() { 
        return Person.count; 
    }
    toString() {
        return `name=${this.name}, tel=${this.tel}, address=${this.address}`;
    }
}

var p1 = new Person('이몽룡', '010-222-3332', '경기도');
var p2 = new Person('홍길동', '010-222-3333', '서울');
console.log(p1.toString());
console.log(Person.getPersonCount());

class Employee extends Person {
    constructor(name, tel, address, empno, dept) {
        super(name,tel,address);
        this.empno = empno;
        this.dept = dept;
    }
    toString() {
        return super.toString() + `, empno=${this.empno}, dept=${this.dept}`;
    }
    getEmpInfo() {
        return `${this.empno} : ${this.name}은 ${this.dept} 부서입니다.`;
    }
}

let e1 = new Employee("이몽룡", "010-222-2121", "서울시", "A12311", "회계팀");
console.log(e1.getEmpInfo());
console.log(e1.toString());
console.log(Person.getPersonCount());

모듈

모듈이란 독립성을 가진 재사용 가능한 코드 블록을 의미한다.
ES2015에서는 모듈을 JS코드를 포함하고 있는 파일이라고 간주해도 무방하다.

코드 블록 안에서 import, export 구문을 이용해서 모듈을 가져오거나 내보낼 수 있다.
모듈 내부에서 선언된 모든 변수, 함수, 객체, 클래스는 local로 간주되기 때문에 외부로 공개하고자 하는 것은 export해 주어야 한다. export된 모듈은 다른 모듈에서 import 구문으로 참조하여 사용할 수 있다.

export

export할 수 있는 대상은 변수, 함수, 객체, 클래스 등이며 다음과 같이 사용한다.

export let a = 1000;
export function f(a) { … }
export { a, b as othername, … }

일단 함수나 변수, 클래스를 작성한 다음 한 번에 export 할 수도 있다.

export { var1, functionAdd };

모듈 단위에서 export 하는 값이 단일 값, 단일 객체, 단일 함수, 단일 클래스라면 deafult 키워드를 이용해 export 한 후 추후에 단일 값으로 import 할 수 있다.

export default functionAdd;

import

import 할 때는 상대경로를 지정하여 사용하고, .js 확장자는 생략할 수 있다.

import { var1, functionAdd } from ‘./utils/utility1’; (구조분해 할당이 이용되는 것)

import 할 때 이름을 변경하고싶다면 as 예약어를 사용할 수 있다.

import { functionAdd as add, var1 as v } from ‘./utils/utility1’;
console.log(v);
console.log(add(4,5));

export default functionAdd; 와 같이 단일 함수를 export한 상태라면,
import functionAdd from ‘./utils/utility1’; 와 같이 단일 값으로 import 할 수도 있다.

Promise

비동기 처리를 깔끔하게 수행할 수 있도록 고안된 객체.

var p = new Promise(function(resolve, reject) {
    setTimeout(function() {
        var num = Math.round(Math.random()*20);
        var isValid = num % 2;
        if (isValid) { resolve(num); }
        else { reject(num); }
    }, 2000);
});

p.then(function(num) {	// 여기에 resolve가 바인딩
    console.log("홀수 : " + num);
}).catch(function(num) {	// 여기에 reject가 바인딩
    console.log("짝수 : " + num);
});

console.log("20까지의 난수중 홀수/짝수?");
console.log("결과는 2초후에 나옵니다.!!");

전개 연산자

가변 파라미터와 다른 개념이며 사용법도 다르다.
기존 객체의 속성이나 배열의 요소들을 포함하여 새로운 객체, 배열을 생성하고자 할 때 사용한다.

let obj1 = { name:"박문수", age:29 };
let obj2 = { ...obj1 };
let obj3 = { ...obj1, email:"mspark@gmail.com" };

console.log(obj2);	// {name: "박문수", age: 29}
console.log(obj3);  	// {name: "박문수", age: 29, email: "mspark@gmail.com"}
console.log(obj1 == obj2);      //false

let arr1 = [ 100, 200, 300 ];
let arr2 = [ "hello", ...arr1, "world"];
console.log(arr2);	// ["hello", 100, 200, 300, "world"]
profile
식지 않는 감자

0개의 댓글