[Sprint #7-1] React - ES6

홍영란·2020년 1월 20일
0

Reference

ES6-destructuring | poiemaweb
ES6features
ES6 문법 정리
Javascript ES6 Cheatsheet | Youtube
개발자가 필히 알아야 할 ES6 10가지 기능
ES6 In Depth: 디스트럭처링(Destructuring)
신선함으로 다가온 ES6 경험 | 우아한 형제들 Dev log


React

Prerequisite

ES6 ?

ECMAScript 2015
ES6 공식문서

자바스크립트와 ECMAScript

넷스케이프(Netscape)에서 1995년 개발한 자바스크립트(javascript)는 웹 브라우저에서 동적인 기능 을 제공하기 위한 언어다. 현재는 대부분의 브라우저에서 이 언어를 제공하고 있다. 그런데 표준 규격없이 여러 브라우저에서 독자적인 특성이 추가되면서 호환성 문제가 발생하기 시작했다. 이에 ECMA 국제 기구에서 “ECMAScript Standard”라는 표준을 만들게 되었다. 정확히 이야기 하자면 현재의 자바스크립트는 ECMAScript
BOM(Browser Object Model)DOM(Document Object Model)을 포괄하는 개념이다

ES6 console

Transpilation(변환)

  • 현재 모든 브라우저에서 ES6 문법을 완벽하게 지원해주지 못한다.
    → 브라우저 호환성 문제를 해결하기 위해 ES6로 작성된 코드를 이전의 문법인ES5 문법으로 transpile 하여 배포해야하는 경우가 발생

Transpile(트랜스파일)

  • 하나의 프로그래밍 언어로 작성된 프로그램의 소스 코드를 입력으로 받아 다른 프로그래밍 언어로 동등한 소스 코드를 만들어내는 컴파일러의 일종.

  • 더 고급의 프로그래밍 언어를 더 저급인 프로그래밍 언어로 변환하는 컴파일러와 달리 트랜스파일러는 코드를 같은 레벨의 다른 언어 로 변환

  • JS Transpiler: JS 코드(ES6) → JS 코드(ES5)로 변환
    Transpile: ES6 -> ES5
    ES6 기능 구현중인 JS 엔진

  • Babel
    Babel is a javascript transpiler. It will transpile (convert from one format to another), ES6 syntax javascript, to ES5 syntax javascript that is runnable in the browser. For this, we will require broccoli-babel-transpiler.

ES6 새로운 기능

Destructuring(비구조화)

: 구조화된 배열 또는 객체를 비구조화하여 개별적인 변수에 할당하는 것

  • 배열과 객체의 패턴 매칭을 통한 데이터 바인딩을 제공
  • 배열 또는 객체 리터럴에서 필요한 값만을 추출하여 변수에 할당하거나 반환할 때 필요
  • Object Destructuring(객체 비구조화)
    : 객체의 각 property를 객체로부터 추출하여 변수 리스트에 할당.
    • 할당 기준은 property name(key)
var user = {
    first: 'Miranda',
    gender: 'Female',
    age: 30
};
// ES5 Syntax
var first = user.first
var last = user.last
// ES6 Syntax
// property key를 기준으로 Destructuring 할당, 순서는 의미가 없음.
// 변수 first, last가 선언되고 객체 user가 Destructuring되어 할당됨
var {first, last} = user;
// first;
// > "Miranda"
  • Array Destructuring(배열 비구조화)
    : 배열의 각 요소를 배열로부터 추출하여 변수 리스트에 할당.
    • 추출/할당 기준은 배열의 index
var Ordinal = ['first', 'second', 'third', 'fourth'];
// ES5 Syntax
var first = Ordinal[0]
var second = Ordinal[1]
var third = Ordinal[2]
var fourth = Ordinal[3]
// ES6 Syntax
// 배열의 index를 기준으로 배열로부터 요소를 추출하여 변수에 할당
// 변수 first, second, third, fourth가 선언되고 배열 Ordinal이 Destructuring되어 할당됨.
var [first, second, third, fourth] = Ordinal;
// second
// > "second"
  • Destructuring(passing values into functions with Objects)
var user = {
    first: 'Miranda',
    last: 'Hart',
    gender: 'Female',
    age: 30
};
// ES5 Syntax
var login = function(person) {
  var first = person.first;
  var last = person.last;
  console.log('Welcome ' + first + ' ' + last + '!');
// ES6 Syntax
var login = function({first, last}) {
  console.log('Welcome ' + first + ' ' + last + '!');
};
// login(user);
// > "Welcome Miranda Hart!"

Spread Operator( ... )

Extended-parameter-handling | poiemaweb
Spread syntax | MDN
: 함수 호출 시 배열을 일련의 인자에 나누어 주입

  • ES6의 Spread 문법(…)을 사용한 배열을 인수로 함수에 전달하면 배열의 요소를 분해하여 순차적으로 파라미터에 할당
  • 배열을 인자(arguments)로 받지 않는 함수에 값을 가진 배열을 인자로 보낼 때 유용하다.
function anonyFunction(a, b, c, d) {
    // do something with a,b, c, and d
};
var arguments = [1, 2, 3, 4];
// ES5 Syntax
// 배열을 분해하여 배열의 각 요소를 파라미터에 전달하고 싶은 경우, 
// Function.prototype.apply를 사용하는 것이 일반적 
// apply 함수의 2번째 인수(배열)는 분해되어 함수 anonyFunction의 파라미터에 전달
anonyFunction.apply(null, arguments);
// ES6 Syntax
/* ...[1, 2, 3, 4]는 [1, 2, 3, 4]를 개별 요소로 분리한다(→ 1, 2, 3, 4)
   spread 문법에 의해 분리된 배열의 요소는 개별적인 인자로서 각각의 매개변수에 전달 */
anonyFunction(...arguments);

Rest Parameters( ... 매개변수)

Rest parameter | MDN
: 정의되지 않은 함수의 매개변수들을 배열에 담을 수 있도록 해준다.
→ pseudo 배열의 매개변수들을 조작할 때 나타나는 복잡도를 줄여준다.

// Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달
function foo(...rest) {
  console.log(Array.isArray(rest)); // true
  console.log(rest); // [ 1, 2, 3, 4, 5 ]
}
foo(1, 2, 3, 4, 5);
// 함수에 전달된 인수들은 순차적으로 파라미터와 Rest 파라미터에 할당
function foo(param, ...rest) {
  console.log(param); // 1
  console.log(rest);  // [ 2, 3, 4, 5 ]
}
foo(1, 2, 3, 4, 5);
function bar(param1, param2, ...rest) {
  console.log(param1); // 1
  console.log(param2); // 2
  console.log(rest);   // [ 3, 4, 5 ]
}
bar(1, 2, 3, 4, 5);
  • Rest 파라미터는 이름 그대로 먼저 선언된 파라미터에 할당된 인수를 제외한 나머지 인수들이 모두 배열에 담겨 할당
    → 따라서 Rest 파라미터는 반드시 마지막 파라미터이어야 한다.
function foo( ...rest, param1, param2) { }
foo(1, 2, 3, 4, 5);
// SyntaxError: Rest parameter must be last formal parameter
  • Rest 파라미터는 함수 정의 시 선언한 매개변수 개수를 나타내는 함수 객체의 length 프로퍼티에 영향을 주지 않는다.
function foo(...rest) {}
console.log(foo.length); // 0
function bar(x, ...rest) {}
console.log(bar.length); // 1
function baz(x, y, ...rest) {}
console.log(baz.length); // 2

※ arguments vs. rest 파라미터
ES5에서는 인자의 개수를 사전에 알 수 없는 가변 인자 함수의 경우, arguments 객체를 통해 인수를 확인한다. arguments 객체는 함수 호출 시 전달된 인수(argument)들의 정보를 담고 있는 순회가능한(iterable) 유사 배열 객체(array-like object)이며 함수 내부에서 지역 변수처럼 사용할 수 있다.

// ES5
var foo = function () {
  console.log(arguments);
};
foo(1, 2); // { '0': 1, '1': 2 }

가변 인자 함수는 파라미터를 통해 인수를 전달받는 것이 불가능하므로 arguments 객체를 활용하여 인수를 전달받는다. 하지만 arguments 객체는 유사 배열 객체이므로 배열 메소드를 사용하려면 Function.prototype.call을 사용해야 하는 번거로움이 있다.

// ES5
function sum() {
  /*
  가변 인자 함수는 arguments 객체를 통해 인수를 전달받는다.
  유사 배열 객체인 arguments 객체를 배열로 변환한다.
  */
  var array = Array.prototype.slice.call(arguments);
  return array.reduce(function (pre, cur) {
    return pre + cur;
  });
}
console.log(sum(1, 2, 3, 4, 5)); // 15
  • ES6에서는 rest 파라미터를 사용하여 가변 인자의 목록배열로 전달받을 수 있다. (이를 통해 유사 배열인 arguments 객체를 배열로 변환하는 번거로움을 피할 수 있다.)
// ES6
function sum(...args) {
  console.log(arguments); // Arguments(5) [1, 2, 3, 4, 5, callee: (...), Symbol(Symbol.iterator): ƒ]
  console.log(Array.isArray(args)); // true
  return args.reduce((pre, cur) => pre + cur);
}
console.log(sum(1, 2, 3, 4, 5)); // 15

하지만 ES6의 화살표 함수에는 함수 객체의 arguments 프로퍼티가 없다. 따라서 화살표 함수로 가변 인자 함수를 구현해야 할 때는 반드시 rest 파라미터를 사용해야 한다.

var normalFunc = function () {};
console.log(normalFunc.hasOwnProperty('arguments')); // true
const arrowFunc = () => {};
console.log(arrowFunc.hasOwnProperty('arguments')); // false

Default Parameters(매개변수 기본값)

// ES5 Syntax
var link = function (height, color, url) {
    var height = height || 50
    var color = color || 'red'
    var url = url || 'http://azat.co'
    ...
}
  • ES6에서는 매개변수 기본값을 사용하여 함수 내에서 수행하던 인수 체크 및 초기화를 간소화할 수 있다.
    • 매개변수 기본값은 매개변수에 인수를 전달하지 않았을 경우에만 유효
// ES6 Syntax
var link = function(height = 50, color = 'red', url = 'http://azat.co') {
  ...
}
  • 단, 주의해야 할 점이 있다. 인자값으로 0 또는 false가 입력될 때 두 예시의 결과는 다르다. ES5에서는 || 처리 시 0 또는 false 값이 입력 되어도 거짓이 되므로 기본값으로 대체된다. 하지만 ES6의 기본 매개 변수를 사용하면 undefined 를 제외한 입력된 모든 값(0, false, null 등)을 인정한다.
function sum(x, y) {
  return x + y;
}
console.log(sum(1)); // NaN
// ES5 Syntax
function sum(x, y) {
  // 매개변수의 값이 falsy value인 경우, 기본값을 할당한다.
  x = x || 0;
  y = y || 0;
  return x + y;
}
console.log(sum(1));    // 1
console.log(sum(1, 2)); // 3
// ES6 Syntax
function sum(x = 0, y = 0) {
  return x + y;
}
console.log(sum(1));    // 1
console.log(sum(1, 2)); // 3
  • 매개변수 기본값은 함수 정의 시 선언한 매개변수 개수를 나타내는 함수 객체의 length 프로퍼티와 arguments 객체에 영향을 주지 않는다.
function foo(x, y = 0) {
  console.log(arguments);
}
console.log(foo.length); // 1
sum(1);    // Arguments { '0': 1 }
sum(1, 2); // Arguments { '0': 1, '1': 2 }

Template Literals

: Template literal이라는 새로운 문자열 표기법 ( $ {}, backticks 사용

  • 템플릿 리터럴은 + 연산자를 사용하지 않아도 간단한 방법으로 새로운 문자열을 삽입할 수 있는 기능을 제공
    → 문자열 인터폴레이션(String Interpolation)
const first = 'Ung-mo';
const last = 'Lee';
// ES5: 문자열 연결
console.log('My name is ' + first + ' ' + last + '.');
// "My name is Ung-mo Lee."
// ES6: String Interpolation
console.log(`My name is ${first} ${last}.`);
// "My name is Ung-mo Lee."
  • 문자열 인터폴레이션은 ${ … }으로 표현식을 감싼다. (문자열 인터폴레이션 내의 표현식은 문자열로 강제 타입 변환)
console.log(`1 + 1 = ${1 + 1}`); // "1 + 1 = 2"
  • Template Literals(Multiple Lines)
    일반적인 문자열에서 줄바꿈은 허용되지 않으며 공백(white-space)를 표현하기 위해서는 백슬래시()로 시작하는 이스케이프 시퀀스(Escape Sequence)를 사용하여야 한다.
    ES6 템플릿 리터럴은 일반적인 문자열과 달리 여러 줄에 걸쳐 문자열을 작성할 수 있으며 템플릿 리터럴 내의 모든 white-space는 있는 그대로 적용된다.
const template = `<ul class="nav-items">
  <li><a href="#home">Home</a></li>
  <li><a href="#news">News</a></li>
  <li><a href="#contact">Contact</a></li>
  <li><a href="#about">About</a></li>
</ul>`;
console.log(template);

Arrow Funtion Expressions

: function 키워드 대신 화살표(=>)를 사용하여 보다 간결한 문법으로 함수를 선언

// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.
// 함수 몸체 지정 방법
x => { return x * x }  // single line block
x => x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.
() => { return { a: 1 }; }
() => ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.
() => {           // multi line block.
  const x = 10;
  return x * x;
};
// ES5 Syntax
var adder = function(x, y) {
    return x + y;
}
// ES6 Syntax
var adder = (x, y) => {
    return x + y;
}
// ES6 Syntax --> 함수가 표현식 하나만 가지는 경우
var adder = (x, y) => x + y;
// _____________________________________________
// 함수가 하나의 매개변수만 받는 경우
// ES5 Syntax 
var square = function(number) {
  return number * number;
}
// ES6 Syntax
var square = number => number * number;
  • 화살표 함수는 익명 함수로만 사용가능 - 화살표 함수를 호출하기 위해서는 함수 표현식 을 사용
// ES5 Syntax
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100
// ES6 Syntax
const pow = x => x * x;
console.log(pow(10)); // 100
  • 콜백 함수 로 사용가능 - 이 경우 일반적인 함수 표현식보다 표현이 간결
// ES5
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // x는 요소값
  return x * x;
});
console.log(pow); // [ 1, 4, 9 ]
// ES6
const arr = [1, 2, 3];
const pow = arr.map(x => x * x);
console.log(pow); // [ 1, 4, 9 ]

Arrow function | poiemaweb

※ function 키워드로 만든 일반함수 vs. 화살표 함수 => "this"

  • 자바스크립트의 경우 함수 호출 방식에 의해 this에 바인딩할 어떤 객체가 동적으로 결정
    • 일반 함수는 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 "동적"으로 결정된다.
// 콜백 함수 내부의 this는 전역 객체 window를 가리킨다.
function Prefixer(prefix) {
  this.prefix = prefix;
}
Prefixer.prototype.prefixArray = function (arr) {
  // (A) this는 생성자 함수 Prefixer가 생성한 객체, 즉 생성자 함수의 인스턴스(위 예제의 경우 pre)
  return arr.map(function (x) {
    return this.prefix + ' ' + x; // (B) this는 전역 객체 window
    /* 생성자 함수와 객체의 메소드를 제외한 모든 함수(내부 함수, 콜백 함수 포함) 내부의 this는 전역 객체를 가리키기 때문 */
  });
};
var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));
  • 화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 "정적"으로 결정
    • 화살표 함수의 this 언제나 상위 스코프의 this를 가리킨다.
      => Lexical this
function Prefixer(prefix) {
  this.prefix = prefix;
}
Prefixer.prototype.prefixArray = function (arr) {
  // this는 상위 스코프인 prefixArray 메소드 내의 this를 가리킨다.
  return arr.map(x => `${this.prefix}  ${x}`);
};
const pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));
  • 화살표 함수는 call, applay, bind 메소드를 사용하여 this를 변경할 수 없다.
window.x = 1;
const normal = function () { return this.x; };
const arrow = () => this.x;
console.log(normal.call({ x: 10 })); // 10
console.log(arrow.call({ x: 10 }));  // 1
※ 화살표 함수를 사용해서는 안되는 경우

ES6-arrow-function | poiemaweb
1. 메소드
2. prototype 할당
3. 생성자 함수
4. addEventListener 함수의 콜백 함수

for ... of loop

for...of | MDN

for...of 명령문은 반복가능한 객체 (Array, Map, Set, String, TypedArray, arguments 객체 등을 포함)에 대해서 반복하고 각 개별 속성값에 대해 실행되는 문이 있는 사용자 정의 반복 후크를 호출하는 루프를 생성

  • Arrays, Sets, Maps 같은 컬렉션에 저장된 모든 값들에 대해서 반복
    • for..of 반복문이 ES6에서 추가 되었으며 for..in 반복문과 달리 iterator 기반의 컬렉션 전용 반복문
// array에 대해 반복
let iterable = [10, 20, 30];
for (let value of iterable) {  // let 대신 const도 사용 가능(블록 내부 변수를 수정하지 않는 경우)
  console.log(value);
}
// 10
// 20
// 30
// string에 대해 반복
let iterable = "boo";
for (let value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"
// Map에 대해 반복
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
  console.log(entry);
}
// [a, 1]
// [b, 2]
// [c, 3]
for (let [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3
// set에 대해 반복
let iterable = new Set([1, 1, 2, 2, 3, 3]);
for (let value of iterable) {
  console.log(value);
}
// 1
// 2
// 3
// DOM 컬렉션에 대해 반복
// 다음 예는 article의 직계 자손인 paragraph에 read 클래스를 추가
// 주의: 이는 NodeList.prototype[Symbol.iterator]가 구현된 플랫폼에서만 작동
let articleParagraphs = document.querySelectorAll("article > p");
for (let paragraph of articleParagraphs) {
  paragraph.classList.add("read");
}

for...of vs. for... in

profile
JavaScript를 공부하고 있습니다:)

0개의 댓글