ES6-destructuring | poiemaweb
ES6features
ES6 문법 정리
Javascript ES6 Cheatsheet | Youtube
개발자가 필히 알아야 할 ES6 10가지 기능
ES6 In Depth: 디스트럭처링(Destructuring)
신선함으로 다가온 ES6 경험 | 우아한 형제들 Dev log
ECMAScript 2015
ES6 공식문서
넷스케이프(Netscape)에서 1995년 개발한 자바스크립트(javascript)는 웹 브라우저에서 동적인 기능 을 제공하기 위한 언어다. 현재는 대부분의 브라우저에서 이 언어를 제공하고 있다. 그런데 표준 규격없이 여러 브라우저에서 독자적인 특성이 추가되면서 호환성 문제가 발생하기 시작했다. 이에 ECMA 국제 기구에서 “ECMAScript Standard”라는 표준을 만들게 되었다. 정확히 이야기 하자면 현재의 자바스크립트는 ECMAScript
와 BOM(Browser Object Model)와 DOM(Document Object Model)을 포괄하는 개념이다
하나의 프로그래밍 언어로 작성된 프로그램의 소스 코드를 입력으로 받아 다른 프로그래밍 언어로 동등한 소스 코드를 만들어내는 컴파일러의 일종.
더 고급의 프로그래밍 언어를 더 저급인 프로그래밍 언어로 변환하는 컴파일러와 달리 트랜스파일러는 코드를 같은 레벨의 다른 언어 로 변환
JS Transpiler: JS 코드(ES6) → JS 코드(ES5)로 변환
Transpile: ES6 -> ES5
※ ES6 기능 구현중인 JS 엔진
: 구조화된 배열 또는 객체를 비구조화하여 개별적인 변수에 할당하는 것
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"
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"
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!"
Extended-parameter-handling | poiemaweb
Spread syntax | MDN
: 함수 호출 시 배열을 일련의 인자에 나누어 주입
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 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);
function foo( ...rest, param1, param2) { }
foo(1, 2, 3, 4, 5);
// SyntaxError: Rest parameter must be last formal parameter
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
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
// ES5 Syntax
var link = function (height, color, url) {
var height = height || 50
var color = color || 'red'
var url = url || 'http://azat.co'
...
}
// ES6 Syntax
var link = function(height = 50, color = 'red', url = 'http://azat.co') {
...
}
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
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 literal이라는 새로운 문자열 표기법 ( $ {}, backticks 사용
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"
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);
: 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 ]
// 콜백 함수 내부의 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']));
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']));
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 명령문은 반복가능한 객체 (Array, Map, Set, String, TypedArray, arguments 객체 등을 포함)에 대해서 반복하고 각 개별 속성값에 대해 실행되는 문이 있는 사용자 정의 반복 후크를 호출하는 루프를 생성
// 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");
}