본문 바로가기
Language/Javascript

ES6 주요 문법 정리 (1) Arrows, Classes, Enhanced Object Literals, Template Strings, Destructuring, Default Parameter, Rest, Spread

by joooing 2021. 1. 7.
반응형

ES6?


일단 ES6이 뭔지부터 살펴보자! ES6은 JavaScript 언어의 표준으로, ECMAScript 6의 줄임말이다. Javascript는 브라우저에서 간단히 사용할 목적으로 2주만에 설계되었는데 역시 짧은 시간에 설계된만큼 허술한 점이 많았다. 개발자들이 점점 개선을 요구한 덕분에(?) 2015년 ECMA2015버전(ES6)이 출시되었고, 기존보다 훨씬 간결하게 코드를 작성할 수 있게 되었다. (혹시 Javascript의 역사가 더 궁금하다면 이 영상에 잘 나와있으니 심심할 때 한번 보는걸 추천한다)

 

그래서 왜 사용한다고..? 🧐

기존 Javascript는 명확하지 않은 문법, 함수, 개념들이 난무했는데 ES6은 이를 보다 명확하게 바꿔서 개발의 생산성을 높였다. 그리고 진입장벽이 낮아져 다른 언어를 사용하던 개발자들도 금방 배울 수 있게 되었다. 그리고 여러 라이브러리들이나 프레임워크도 ES6기반으로 구성되어 있어서, 이미 대중적으로 사용하고 있는 상태라고 한다. (현재 ES6 기능들을 구현 중인 Javascript엔진 목록이 궁금하다면 여기서 확인해볼 수 있다.) 무엇보다 익숙해지면 기존보다 훨씬 간결하고 편하게 코드를 구현할 수 있다고 한다!

 

ES6의 새로운 기능 목록 🗒

ES6은 아래 목록처럼 새로운 기능을 많이 포함하고 있다. 차례대로 하나씩 살펴보도록 하자. 중간중간 좀 더 근본적인 개념에 대한 보충이 필요하거나, 설명이 부족하다고 느껴지는 부분들에는 공부하면서 도움이 되었던 참고 자료들의 링크를 걸어뒀으니 함께 참고하며 읽어보면 좋을 것 같다. 그래도 어려운 부분이 있다면 우선은 예시만 보고 넘어가도 사용하는 데 지장은 없을 것 같다. 한번에 다 보기에는 꽤 많은 양이라 이번에는 Arrows부터 Default + Rest + Spread 부분까지만 먼저 소개해보려고 한다.

 

 

Arrows (화살표 함수, =>)


=> 기호로 함수를 축약해서 표현하는 방식이다. 아래 예시를 보면, 전 ⇒ 후 형태로 표시되기 때문에 훨씬 직관적으로 내용을 파악할 수 있다는 걸 알 수 있을 것이다.

 

✔️ 자신의 this, arguments을 바인딩 하지 않음 (상위(lexical) 스코프를 가리키는 lexical this를 가짐)

✔️ 메서드 함수가 아닌 곳에 가장 적합하기 때문에 생성자로 사용 불가

 

// 기본 구조
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression

// 매개변수가 하나면 경우 괄호 생략 가능
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없으면 괄호만 사용
() => { statements }

 

// 예시
const sum = (a, b) => a + b;

// 매개변수가 하나면 경우 괄호 생략 가능
const evens = [2, 4, 6, 8,];
const odds = evens.map(v => v + 1);   
// [3, 5, 7, 9]
const pairs = evens.map(v => ({even: v, odd: v + 1})); 
// [{even: 2, odd: 3}, ...]

 

 

Classes (클래스)


JavaScript 클래스는 Prototype기반의 상속을 사용하며 객체지향 패턴을 보다 쉽게 사용할 수 있게 도와주는 역할을 한다. 클래스를 사용하는 이유는 특정 구조의 객체를 여러 곳에서 사용하는 경우, 필요에 따라 인스턴스를 생성해 재사용이 가능하기 때문이다. 

 

✔️ 키워드로 새로운 객체를 생성해 메서드를 호출하고 결과값을 출력

      → class : 새 클래스 선언 + 속성/메서드 정의

      → new : 호출

✔️ 이름을 지정해도 되고(기명,named), 안해도됨(익명,unnamed)

      → 이름이 있는 경우 클래스 본체(body)만 지역(local)으로함

 

주의사항

✔️ 다른 언어와 비슷한 키워드를 쓰지만 작동방식은 다르다! (여기선 Syntax적 표현일 뿐..)

✔️ Class는 Hoisting 이 되지 않기 때문에 사용을 위해서는 선언부터 해야 한다!

 

const Myclass = new Myclass(); // ReferenceError(참조오류)
class Myclass {}

 

// 예시 (사각형 넓이 구하기)
const Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  area() {
    return this.height * this.width;
  }
};

new Rectangle(5, 6).area();
// 30

 

 

Enhanced Object Literals (향상된 객체 리터럴)


향상된 객체 리터럴.. 무슨 말인가 싶지만 생각보다 뜻은 단순하다. 기존의 객체를 선언하는 방식을 개선했다는 의미이다. 자주 사용하던 Javascript 문법들을 좀 더 간결하게 사용할 수 있도록 객체 선언 방식을 바꾼 것이다.

기존에는 객체를 바로 아래와 같은 방식으로 정의했다. 이 형태를 기억하고 바뀐 방식을 살펴보도록 하자! 코드가 훨씬 간략해진걸 확인할 수 있을 것이다.

 

const student = {
  name: 'jooing',
  sayHi: function() {
    console.log('Hi!!');
  }
};

 

1) (속성 = 값)이면 한개는 생략 가능

객체의 속성(property)와 값(value)이 같으면 아래처럼 하나는 생략할 수 있다.

 

const name = 'jooing';
const student = {
	name    // name: name
};

console.log(student);    // {name: 'jooing'}

 

2) 함수가 속성값일 때 function 예약어 생략 가능

객체의 속성값으로 함수를 정의하는 경우가 종종 있는데, 기존에는 function 예약어를 사용해서 선언을 했었다. 하지만 ES6문법을 사용하면 이부분(function)을 과감히 지워버리고 함수를 정의할 수 있다! 생략 전과 후를 비교해보자.

 

// before
const student = {
  sayHi: function() {
    console.log('Hi!!');
  }
};
student.sayHi();   // Hi!!

// after
const student = {
  sayHi() {
    console.log('Hi!!');
  }
};
student.sayHi();   // Hi!!

 

 

 

Template Strings (Template literals, ``)


✔️ 문자열(String)을 생성할 때 문법적으로 더 편하게 해줌

✔️ ' '(작은 따옴표), " "(큰 따옴표) 대신 ``(backtick, 백틱) 기호를 사용

 

줄바꿈할 때

기존 문법인 ' ' 또는 " " 안에서 줄바꿈을 하면 에러(SyntaxError)가 발생한다. 하지만 ``(backtick)을 사용하면 정상 작동하게된다. 아래처럼 콘솔창에 두 가지 경우를 직접 입력해보며 뭐가 다른지 확인해보자!

 

변수 + 문자열 함께 사용하기

변수와 문자열을 혼용해서 사용하는 경우, 백틱기호를 사용하면 유용하고 가독성도 향상된다. 기존에는 + 기호를 사용해서 일일이 더해주는 식이었지만 (변수가 많아질수록 가독성이 점점 떨어지고 거슬린다..) 백틱기호를 쓰면 변수를 ${변수} 형태로 중간에 끼워넣을 수 있기 때문에 훨씬 보기 편하다. 전과 후를 비교해보자.

 

const name = 'jooing';
console.log(name + ' blog');    // before
console.log(`${name} blog`);    // after
// jooing blog

 

 

 

Destructuring (디스트럭처링, 구조 분해 할당)


✔️ 배열, 객체를 좀 더 쉽게 다루는 방식

✔️ 배열, 객체 속성을 분해해서 그 값을 개별 변수에 담을 수 있게 하는 표현식

 

함수에 객체나 배열을 전달할 때, 전체가 아닌 일부만 쓰고 싶은 경우가 생길 수 있다. 이 때 객체나 배열을 변수로 분해할 수 있게 해주는 것이 바로 '구조 분해 할당(destructuring assignment)' 이다. 매개변수가 많거나 매개변수 기본값이 필요한 경우나 spread opeator(...), 각 배열의 원소를 하나씩 가져오는 경우 등에 유용하게 쓸 수 있다.

 

객체

일단 객체의 경우 어떤 식으로 사용할 수 있는지부터 살펴보자. 변수명이 있어야 할 자리에 {중괄호}가 등장해서 낯설게 느껴질 수 있다,,

 

const wish = {
  name : 'applewatch',
  price : 500000
};

const { name, price } = wish;
console.log(name); 
// applewatch

 

배열

이번에는 배열을 한 번 살펴보도록 하자. 값을 별도의 변수에 할당하려는 경우, destructuring을 통해 간단하고 깨끗하게 할당할 수 있다. index나 반복문을 사용할 필요도 없어진다.

 

const arr = [1, 2, 3, 4];
const [first, second, third, fourth] = arr;

console.log(first);
// 1

 

주의사항

✔️ 할당 연산자 왼쪽에는 객체리터럴이 와야 하고, 오른쪽에는 null이나 undefined가 오면 안된다!

✔️ 변수 선언시에는 반드시 초기자(initializer)를 할당해줘야 한다!

 

 

 

Default Parameter (기본 매개변수)


default parameter는 말 그대로 '초기 설정된 매개변수의 값'을 말한다. 함수에 전달된 매개변수가 undefined거나, 전달된 값이 없을 경우 초기 지정된 값이 이용되는 것이다.

 

이것도 예제를 바로 보며 이해하는게 빠를 것 같다. 매개변수를 모두 전달해 준 경우(sum(2, 3))에는 두 값이 사용된 결과가 반환된다. 반면 매개변수가 한개만 전달 된 경우(sum(5))에는 나머지 하나의 값으로 기본 매개변수값으로 지정했던 값이 사용된다.

 

function sum(a, b = 10) {
  return a + b;
}

sum(2, 3);    // 5
sum(5);       // 15

 

// 또 다른 예제
function printName (name = 'jooing') {
  console.log(name);
}

printName();		 // jooing
printName('noname');	// noname

 

 

 

Rest Parameter (...)


매개변수의 개수가 정해지지 않은 경우, 전달받은 모든 매개변수들을 배열로 나타낼 수 있게 해준다. 사용방법은 매개변수 앞에 ...을 붙이면 끝! 아래 부분의 또 다른 예시를 보면 알 수 있듯이 Rest Parameter이라는 이름 그대로 나머지 매개변수들을 하나의 배열로 만들어주는 역할을 한다.

 

function getNumber(...nums) {
  return nums; // [ 1, 2, 3, 4 ]
}
getNumber(1, 2, 3, 4);

 

// 또 다른 예시
function getNumber(param, ...rest) {
  console.log(param); // 1
  console.log(rest);  // [ 2, 3 ]
}
getNumber(1, 2, 3);

 

 

 

Spread Operator (...)


Spread Operator(전개 연산자)는 바로 앞에서 설명한 Rest Parameter와 마찬가지로 ... 을 사용한다. 그럼 뭐가 다른걸까? 둘은 반대로 작동한다고 이해하면 쉽다. 앞서 배운 Rest Parameter는 각각의 요소들을 하나의 배열로 묶어주는 반면, Spread Operator는 배열로 묶인 개별 요소들을 펼쳐준다. (헷갈린다면 각 예제를 유심히 보며 비교해보자) 한글로 '전개 연산자'라고 부르기도 하는데 말 그대로 받아온 모든 변수들을 배열로 펼쳐서 보여주기 때문이다. 배열, 문자열처럼 반복 가능한(Iterable) 객체들에 적용할 수 있다.

 

// Array(배열)
console.log(...[1, 2, 3]); // 1, 2, 3
 
// String(문자열)
console.log(...'Hello');  // H e l l o

 

// 또 다른 예제
function getNumber(a, b, c) {
  console.log(a); // 1
  console.log(b); // 2
  console.log(c); // 3
}
const arr = [1, 2, 3];
getNumber(...arr);

 

 

 

여기까지 ES6문법 중 가장 많이 접하고 직접적으로 사용하는(?) 대표적인 몇 개의 문법들을 소개해봤다. 다음에는 let, const부터 generators, modules 등 더 다양한 ES6 문법들에 대해 알아볼 예정이다.

반응형

댓글