[태그:] ES6

  • ES6

    1. ES6 문법(ES2015)

    ⭐ES6문법

    ES(ECMAScript)란 자바스크립트의 표준을 말하며

    자바스크립트가 다양한 웹 브라우저에서 공통적으로 잘 작동되도록 표준이 필요해지면서 만들어진 것.

    ES6가 가장 큰 변화가 있는 표준.

    1) const & let (불변 변수와 가변 변수)

    (1) const

    불변 변수 선언을 위한 키워드로,

    객체와 함께 사용할 때 말고는 값을 다시 할당할 수 없는 변수. (배열이나 객체의 값을 변경하는 것은 가능하다)

    보통 const를 사용하며 var 사용보다는 const나 let을 사용.

    (2) let

    가변 변수 선언을 위한 키워드,

    즉, 변경 가능한 변수를 생성할 수 있다. const와 달리 재할당이 가능한 변수.


    2) 템플릿 문자열(Template String)

    문자열 안에 변수, 연산식을 혼합하여 사용한다.

    (1) 작은따옴표( ‘ ‘ ) 대신 백틱( ` )으로 문자열 표현.

    (2) 템플릿 문자열에 $를 사용하여 변수나 식 포함 가능.

    기존의 코드:

    var fruit = { name: '망고', price: 9900 };
    var getFruit = function(fruit) {
        return fruit.price + '원';
    };
    var mine = '선택한 과일은 ' + 'fruit.name + '입니다. 가격은 ' + getFruit(fruit) + '입니다.';

    템플릿 문자열:

    var fruit = { name: '망고', price: 9900 };
    var getFruit = function(fruit) {
        return ${fruit.price}원;
    };
    var mine = `선택한 과일은 ${fruit.name}입니다. 가격은 ${getFruit(fruit)}입니다.`;

    3) 전개 연산자(Spread Operator)

    나열형 자료를 추출, 연결할 때 사용.

    사용하려면 배열 또는 객체, 변수명 앞에 마침표 세개(…) 입력.

    기존의 코드:

    const arr1 = [1,2,3];
    const arr2 = [4,5,6];
    const combined = arr1.concat(arr2);

    전개 연산자:

    const arr1 = [1,2,3];
    const arr2 = [4,5,6];
    const combined = [...arr1, ...arr2];

    또다른 예시로 객체의 경우,

    기존의 코드:

    const obj1 = { one: 1, two: 2 };
    const obj2 = { three: 3, four: 4 };
    
    var combined = Object.assign({}, obj1, obj2);

    전개 연산자:

    const obj1 = { one: 1, two: 2 };
    const obj2 = { three: 3, four: 4 };
    
    var combined = {...obj1, ...obj2};

    4) 화살표 함수(Arrow function)

    화살표 기호 => 로 함수를 선언. function 키워드를 생략하고 인자 블록과 본문 블록 사이에

    화살표를 표기하여 사용한다.

    기존의 코드:

    function addNumber(a,b) {
        return a+b;
    }

    화살표 함수:

    const addNumber = (a,b) => {
        return a+b;
    }

    return 키워드를 생략하면

    const addNumber = (a,b) => a+b;

    5) 클래스(Class)

    기존 자바스크립트(ES5까지)에는 클래스가 없었으나 ES6에 추가됨.

    (1) 클래스 사용법

    ① class 키워드: 클래스 정의

    ② constructor() 생성자 함수

    ③ new 키워드: 클래스 생성

    자세히는 Java Script – Class 장에서 다룬다.

    클래스를 사용한 코드:

    class addUser {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
    }
    
    const user = new addUser('AAA', 24);
    
    console.log(user.name);// AAA

    6) 객체 확장 표현식(Enhanced Object property) & 구조 분해 할당(Destructuring assignment)

    (1) 객체 확장 표현식(Enhanced Object property)

    key-value(키 이름과 값) 데이터 형식의 객체를 확장하여 표현 가능.

    객체 내부에서 표현식을 사용하거나 키와 키값을 편리하게 저장할 수 있음.

    ① 객체 변수를 선언 시 키값을 생략하면 자동으로 키의 이름으로 키값을 지정.

    ② 객체 생성 블록안에 대괄호로 묶어 그 안에 표현식을 작성 → 계산된 key 값 사용 가능.

    ③ function 키워드를 생략하여 함수 선언 가능.

    기존의 코드:

    const a = 0;
    const b = 0;
    
    const obj = { a: a, b: b };
    console.log(obj);// { a: 0, b: 0 }const ord = "first";
    const combined = {};
    combined[ord + "Key"] = "value";
    console.log(combined);// { firstKey: 'value' }

    객체 확장 표현식:

    const a = 0;
    const b = 0;
    
    const obj = { a, b };
    console.log(obj);// { a: 0, b: 0 }const ord = "first";
    const combined = { [ord + "Key"]: "value" };
    console.log(combined);// { firstKey: 'value' };

    (2) 구조 분해 할당(Destructuring assignment)

    배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있도록 함.

    구조 분해 할당은 함수 인자값을 다루거나 JSON 데이터 변환할 때 유용하며 전개 연산자와 함께 사용됨.

    ① 배열에서 값을 추출할 때: 인덱스 순서에 맞게 변수 작성

    ② 변수에 =(선언 부호, 할당 연산자)를 함계 사용하여 기본값 할당 가능

    ③ 객체에서 값을 추출할 때 키의 이름과 동일반 변수 이름 사용

    ④ 객체에서 값을 추출할 때 변수에 :(콜론) 부호를 사용하여 새 변수명으로 키값을 할당 가능.

    ⑤ sqap을 간편하게 구현 가능.

    기존의 코드:

    const list = [1, 4];
    const item1 = list[0];
    const item2 = list[1];
    
    const obj = {
        key1: "one",
        key2: "four",
    };
    const key1 = obj.key1;
    const key2 = obj.key2;

    ES6 구조 분해 할당:

    const list = [1, 4];
    const [item1, item2] = list;
    
    const obj = {
        key1: "one",
        key2: "four",
    };
    const { key1, key2, key3 = "eight" } = obj;

    7) 비동기 함수

    (1) 비동기 처리

    작업 시간을 많이 요하는 작업을 처리하는 동안 다른 작업들이 대기 상태인 경우,

    다른 작업들을 먼저 진행하고 오래 걸리는 작업과 그 작업에 관련된 작업을 이후에 처리하는 방식.

    (2) 프로미스(Promise)

    ✍🏻 프로미스의 상태 세 가지

    • 대기중: 결과를 기다리는 중
    • 처리됨 – 이행됨: 수행이 정상적으로 끝남. 결과값을 갖고 있음
    • 처리됨 – 거부됨: 수행이 비정상적으로 끝남.

    ① 프로미스 생성: new 키워드로 생성.

    ② Promise.resolve 생성: 이행됨 상태인 프로미스 생성

    ③ Promise.reject 생성: 거부됨 상태인 프로미스 생성.

    ④ then : 처리됨 상태가 된 프로미스를 처리할 때 사용하는 메소드.

    기존의 비동기 함수:

    function work1(onDone) {
        setTimeout ( () => onDone('작업1 완료.'), 100);
    }
    function work2(onDone) {
        setTimeout ( () => onDone('작업2 완료.'), 200);
    }
    function urgentWork() {
        console.log('긴급 작업');
    }
    
    work1(function(msg1) {
        console.log('done after 100ms: ' +msg1);
        work2(function(msg2) {
            console.log('done after 300ms: ' +msg2);
        });
    });
    urgentWork();

    우선 순위: (setTimeout이 걸려있지 않으므로) urgentWork() > work1 > work2

    지연 작업(work1, work2, …)의 수가 늘어날수록 콜백이 계단으로 형성: 콜백 지옥(callback hell) 발생.

    ✍🏻콜백 지옥(callback hell)

    • 가독성이 떨어짐(코드가 길어진다)
    • 코드 수정이 어려움
    • 비즈니스 로직을 한눈에 알아보기 어려움

    ES6의 비동기 처리:

    const work1 = () =>
        new Promise((resolve) => {
            setTimeout(() => resolve('작업1 완료.'), 100);
        });
    const work2 = () =>
        new Promise((resolve) => {
            setTimeout(() => resolve('작업2 완료.'), 200);
        });
    const urgentWork = () => {
        console.log('긴급 작업');
    }
    
    const nextWorkOnDone = (msg1) => {
        console.log('done after 100ms: ' + msg1);
        return work2();
    }
    work1()
        .then(nextWorkOnDone)
    
        .then((msg2) => {
            console.log('done after 300ms: ' + msg2);
        });
    urgentWork();

    8) 배열 함수

    (1) forEach()

    반복문의 순번(i++)과 배열의 크기를 따로 선언하는 과정을 생략할 수 있음.

    forEach()가 내장함수이므로 속도 부분으로는 for()보다 더 빠르다.

    • 반환값이 없어도 됨
    • 문법
    arr.forEach(callback(currentValue[, index[, array]])[, thisArg])

    • callback: 각 요소를 실행할 함수, currentValue와 index, array 세 가지 매개변수를 받음.



    • currentVaule: 처리할 현재요소



    • index: 처리할 현재 요소의 index.



    • array: forEach()를 호출한 배열.



    • thisArg: callback을 실행할 때 this로 사용하는 값


    forEach()를 사용한 코드(1):

    const arr = [1, 2, 3, 4, 5];
    const odd = [];
    
    arr.forEach(function(num){
        if(num%2 == 1) {
            odd.push(num);
        }
    });
    
    console.log(odd);// [1, 3, 5]

    forEach()를 사용한 코드(2):

    const useQuery = "a=1,b=2,c=3"
    
    function parser(qs) {
    
        const queryString = qs.substr(0);
        const splitedStr = queryString.split(',');//splitedStr=['a=1','b=2','c=3']let result = {};
    
        splitedStr.forEach((str) => {
            const [key, value] = str.split('=');
            result[key]=value;
        });
        return result;
    }
    console.log(parser(useQuery));
    
    // {a: '1', b: '2', c: '3'}

    (2) map()

    배열 요소를 정의된 함수를 통해 새 배열을 만드는 함수.

    ※ 반환값 필요.

    • 문법
    arr.map(callback(currentValue[, index[, array]])[, thisArg])

    • callback: 배열의 모든 요소에 적용되어 새 배열 요소를 생성.



    • currentVaue: callback이 적용될 현재 요소



    • index: 처리할 현재 요소의 index



    • array: map()를 호출한 배열



    • thisArg: callback을 실행할 때 this로 사용하는 값


    map()을 사용한 코드(1):

    const arr1 = [1, 2, 4, 8];
    const doubleArr = numbers.map((arr1) => {
        return arr1 * 2;
    });
    console.log(doubleArr);// [2, 4, 8, 16]

    map()을 사용한 코드(2):

    const useQuery = "a=10,b=20,c=30"
    function parser(qs) {
        const queryString = qs.substr(0);// queryString = a=10,b=20,c=30"const splitedStr = queryString.split(',');// splitedStr = ['a=10', 'b=20', 'c=30']
    
        const result = splitedStr.map((str) => {
            const [key, value] = str.split('=');
            return {key: key, value: value};// {key: 'a', value: '10'}
        });
        return result;
    }
    
    console.log(parser(useQuery));
    
    /* result = [
        {key: 'a', value: '10'},
            {key: 'b', value: '20'},
            {key: 'c', value: '30'}
       ];
    */

    (3) reduce()

    배열의 요소를 순차적으로 순회하며 reducer 함수를 실행하고 하나의 결과값을 반환,

    그 결과값은 객체나 배열, 스트링 등이 될 수 있음

    • 문법
    arr.reduce(callback[, initialValue])

    • callback: 배열의 각 요소에 대해 실행, 네 가지 인수를 받음.



    • accumlator(누적값): 누산기. callback의 반환값을 누적.



    • currentValue(현재값): 처리할 현재 요소



    • currentIndex(현재 인덱스): 처리할 현재 요소의 index(initialValue를 제공한 경우: 0, 아니면 1부터 시작)



    • array(현재 배열): reduce()를 호출한 배열.



    • initialValue(초깃값): callback의 최초 호출에서 첫 번째 인수에 제공하는 값


    🌟 reduce의 accumulator와 currentValue

    ① accumulator(누적값)

    accumulator는 callback의 반환값을 누적하는데, 이 누적값이 없거나 초깃값을 제공한 경우

    initialValue(초깃값)로 시작함.

    ② initialValue(초깃값)

    initialValue를 설정하지 않았을 경우: accumulator가 배열의 0번째 index, currentVaule가 첫 번째 index

    initialValue를 설정한 경우: accumulator가 initialValue, currentVaule가 0번째 index

    즉, reduce가 순회하면서 accumulator에 반환값을 누적시키며 하나의 값을 리턴.

    • 배열이 비어있는데 초깃값을 제공하지 않을 경우: 에러 발생

    reduce()를 사용한 코드(1):

    const arr = [1, 2, 3, 4, 5];
    const initialValue = 0;
    
    const reduceArr = arr.reduce((accumulator, currentValue) =>
        accumulator + currentValue, initialValue
    );
    
    console.log(reduceArr);// 15

    reduce()를 사용한 코드(2):

    const useQuery = "a=1&b=3&c=5"
    function parser(qs) {
        const queryString = qs.substr(0);// queryString = a=1&b=3&c=5"const splitedStr = queryString.split('&');// splitedStr = ['a=1', 'b=3', 'c=5']
    
        return splitedStr
            .map((str) => {
                const [key, value] = str.split('=');
                return {key, value};
            })
            .reduce((result, arr) => {
                result[arr.key] = arr.value;
                return result;
            }, {});
    
    }
    
    console.log(parser(useQuery));
    
    // {a: '1', b: '3', c: '5'}