인프런 강의 기반으로 ES6 문법을 정리한 내용입니다.

📕 Scope


변수 선언

다음 세 가지를 기억하자

  1. const를 기본으로 사용한다.
  2. 변경이 될 수 있는 변수는 let을 사용한다.
  3. var는 사용하지 않는다.

let

block (function, for, if 등) 안에서 유효한 변수

const

const는 수정 불가능한 불변성(immutable)을 말하는 것이 아니라 값 재할당이 불가능한 것이다.
const를 사용하더라도, 배열과 오브젝트의 값을 변경하는 게 가능하다.

    const list = ["godori", "irodog", "roodig"];
    list.push("dorigo");
    console.log(list);  // ["godori","irodog","roodig","dorigo"]

immutable array

다음과 같은 예제를 보면, 기존 배열을 두고 새로운 배열을 만들어 데이터를 추가한다.

    const list1 = ["goodori", "irodog", "roodig"];
    list2 = [].concat(list1, "dorigo");
    console.log(list1 === list2);  // false

리액트 등에서 state값이 변경되는 경우를 예로 들 수 있다.

주로 리덕스의 리듀스를 이용해 새로운 값을 계속 반환할 때 immutable array를 많이 사용하게 된다.

immutable.js라는 라이브러리를 쓰면 객체 원본은 그대로 두고 복사본을 만드는 방법을 제공한다.

혹은 ES6의 스프레드 연산자를 사용하는 방법도 존재.

📗 String


ES6에 추가된 새로운 string메서드들

  • startsWith() , endsWith() : 앞 뒤로 일치하는 문자열이 있는지 여부를 판단
  • includes() : 문자열이 포함되어 있는지 여부를 판단
      let str = "godori is irodog";
      str.startsWith("godori");  // true
      str.endsWith("irodog");    // true
      str.includes("is");        // true
    

📘 Array


for-of 순회

기존 for-in 배열 순회 :
자기 자신에게는 없는 상위 프로토타입의 값도 포함될 수 있다는 문제가 있었다.

    var data = ["irodog", "roodig"];
    Array.prototype.getIndex = "godori";

    for(let idx in data){
        console.log(data[idx]); // irodog, roodig, godori
    }

for of 순회 :
index가 아닌 value 순회가 가능하므로 for-in과 같은 문제를 방지할 수 있다.

    var data = ["irodog", "roodig"];
    Array.prototype.getIndex = "godori";

    for(let value of data){
        console.log(value); // irodog, roodig
    }

spread 연산자

[ ... arr] 와 같이 표기한다

원본 배열을 바꾸지 않고 열거 가능한 요소를 하나씩 전개한다.

    let data = ["godori", "irodog", "roodig"];
    let newData = [...data];
    console.log( newData === data );  // false

spread 연산자 활용

    function sum(a,b,c){
        return a+b+c;
    }
    let arr = [100,200,300];

    console.log( sum.apply(null, arr) );  // 인자를 배열 형태로 받아 출력
    console.log( sum(...arr) );           // 이렇게 써도 동일한 결과 출력

from으로 진짜 배열 만들기

JS 함수에는 arguments라는 유사 배열이 존재하며, 함수 호출시 입력한 인자들을 저장하고 있다.
하지만 이는 arguments 객체의 인스턴스로, 배열과 흡사하지만 엄밀한 의미로 배열이 아니다.

따라서 다음과 같이 배열 메서드인 map 등은 arguments에 사용 불가능하다

    function apendDoggy(){
        let newData = arguments.map(function(value) {
            return value + "🐶";
      });

        console.log(newData);
    }

    apendDoggy("bow","wow"); // [ERROR!!] map을 사용할 수 없다

from 함수를 사용하면 유사 배열을 배열로 만들어준다.
가령, DOM조작시 querySelectAll로 얻은 노드 리스트를 from 을 통해 배열로 변경할 수도 있다.

    function apendDoggy(){
        let newArray = Array.from(arguments);
        let newData = newArray.map(function(value) {
            return value + "🐶";
      });

        console.log(newData);
    }

    apendDoggy("bow","wow"); // ["bow🐶","wow🐶"]

📙 Object


Object 생성시에 key와 value가 같다면 간략하게 하나만 사용할 수 있다.
또한, value 값만 전달하거나 function도 바로 선언할 수 있다.

    function getObj(){
        const name = "godori";

        const getName = function() {
            return name;
        }

        const setName = function(newName) {
            name = newName;
        }

        const printName = function(){
            console.log(name);
        }

    // 기존
        return {
            getName : getName,
            setName : setName
        }

    // ES6
     return { getName, setName, name , myFunction(){ ...} } 

        var obj = getObj();
        console.log(obj.getName());
    }

📒 Destructuring


구조 분해 Destructuring 를 사용하면 객체나 배열의 필드 값을 원하는 개별 변수에 대입할 수 있다.

Destructuring Array

배열 선언시 원하는 인덱스의 값을 다음과 같이 변수로 할당할 수 있다.
콤마를 사용하여 불필요한 값을 무시할 수 있는 리스트 매칭도 가능하다.

    let data = ["godori", "cheeze", "rajephon", "kine"];

    // 일반적으로 배열 데이터를 가져오는 방법
    let name1 = data[0];
    let name2 = data[1];

    // ES6에서는 다음과 같이 표현 가능
    let [name3, ,name4] = data;

    console.log(name3, name4); // godori , rajephon

Destructuring Object

객체에서도 필요한 데이터만 뽑아서 변수로 할당할 수 있다.

    let obj = {
        name: 'godori',
        address: 'Guldari',
        age: 17
    }

    // 객체의 키 이름 값으로 새로운 변수 만들기
    let {name, age} = obj;

    // 다른 변수 이름으로 객체의 값을 할당 받기
    let {name:myName, age:myAge} = obj;

    console.log(name, age, myName, myAge); // godori, 17, godori, 17

Destructuring 활용

  • JSON으로 전달받은 데이터 객체를 개별 변수로 할당하는 데 활용할 수 있다.
  • 함수의 인자에 Destructuring을 사용하면 원하는 데이터만 뽑아낼 수 있다.
  • 이벤트의 콜백 함수에서 필요한 요소만 뽑아올 수 있다.

      document.querySelector('div').addEventListener('click',
       function(ev) {       // event 전체가 아니라 필요한 요소만 뽑을 수있다.
          console.log(ev.target);
      })
    
      document.querySelector('div').addEventListener('click', 
          function({target, type}) { // 인자 전달 시 target이나 type만 뽑아낼 수 있다.
              console.log(target.tagName, type);
      })
    

📕 Set / WeakSet


중복 없이 유일한 값을 저장할 때 set을 사용하며, 순회가 가능하다.
이미 값이 존재하는지 체크할 때 유용하다.

    let mySet = new Set()

    mySet.add('godori')
    mySet.add('irodog')
    mySet.add('godori')

    mySet.forEach(function(v){
        console.log(v); // godori, irodog (중복된 값은 나오지 않음)
    })

    console.log(mySet.has('godori')) // 값을 가지고 있는지? true

weakset은 참조를 가지고 있는 객체만 저장이 가능하다.

따라서 weakset의 객체가 null 이 되거나 필요 없어지면 가비지 컬렉팅의 대상이 된다.
이는 컬렉션 내에 저장된 객체 목록이 없음을 뜻하고, weakset은 열거 불가능하다

    let arr = [1,2,3,4]
    let ws = new WeakSet()

    ws.add(arr)           // ⭕️ valid
    ws.add(111)           // ❌ invalid!
    ws.add('111')         // ❌ invalid!
    ws.add(null)          // ❌ invalid!
    ws.add(function(){})  // ⭕️ valid

    // 참조가 사라진 경우, weakset에서도 제거된다.
    let arr2 = [5,6,7,8]
    let obj = {arr, arr2}
    ws.add(arr)
    ws.add(arr2)
    ws.add(obj)

    arr = null
    console.log(ws)  // arr이 표시된다! 그래서 마치 weakset에 포함된 것 같지만...
    console.log(ws.has(arr)) // false! 실제론 null이 된 것을 알고있다.
    console.log(ws.has(arr2)) // true