ECMAScript 6(ES6)는 EMCAScript 2015라고도 하는데, 자바스크립트의 두번째 주요 개정판입니다.
EMCAScript 2015 이전에는 전역 범위와 함수 범위만 존재했습니다. ES6 이후로 let과 const 키워드의 등장으로 블록 범위가 적용되었습니다.
let 키워드는 블록 범위에서 변수를 선언할 수 있습니다. (기존의 var 키워드는 함수 스코프에서 변수를 선언했습니다.)var키워드와 달리 재선언을 할 수 없습니다.// Global of Function Scope
{
// Block Scope
var x = 5;
let y = 10;
let y = 5; // Uncaught SyntaxError: Identifier 'y' has already been declared
}
console.log(x); // 5
console.log(y); // Uncaught ReferenceError: x is not defined
var x = 10;
console.log(x); // 10
const 키워드로 선언한 변수는 블록 범위를 가지고, 상수로서 값을 재할당할 수 없고, 재선언도 할 수 없습니다.// Global of Function Scope
{
// Block Scope
const x = 10;
x = 5; // Uncaught TypeError: Assignment to constant variable.
const x = 5; // Uncaught SyntaxError: Identifier 'x' has already been declared
}
console.log(x); // Uncaught ReferenceError: x is not defined
const로 선언하는 것이 좋습니다.const add = (x, y) => x + y; // 함수가 한 줄로 작성될 경우, return 키워드를 생략할 수 있다.
const sub = (x, y) => { // 여러 줄인 경우, 일반 함수의 중괄호처럼 작성해도 된다.
return x - y;
};
console.log(add(2, 3)); // 5
this를 가지고 있지 않습니다. 그래서 객체 메서드로 사용하기엔 부적합합니다.const obj = {
foo: function() {
console.log(this); // {foo: ƒ, bar: ƒ}
},
bar: () => {
console.log(this); // window(broswer) or {}(node)
}
}
obj.foo();
obj.bar();
console.log(foo()); // 10
console.log(bar()); // ReferenceError: Cannot access 'bar' before initialization
function foo() {
return 10;
}
const bar = () => 10;
for...of 반복문은 반복 가능한 객체(Array, String, Map, Set, NodeList 그 외 [Symbol.iterator] 속성을 가진 객체)의 값을 순회합니다.value는 var, let, const 등으로 선언될 수 있지만, 반복문의 블록 스코프 내에서만 변수를 사용할 경우, 그리고 변수를 재할당할 일이 없을 경우 const로 선언하는 편이 좋습니다.value의 값을 변경해도 iterable의 값이 수정되지 않습니다. for (const value of iterable) {
// 반복문의 블록 범위
}
for...in 반복문은 객체의 속성을 순회합니다.for (const key in object) {
const value = object[key]
// 반복문의 블록 범위
}
key 값으로 설정됩니다. 하지만, 객체는 속성의 순서를 보장하지 않으므로 배열과 사용하면 안됩니다.for (const index in array) {
console.log(array[index]); // 순서를 보장하지 않음!
}
class 키워드로 자바스크립트에서 객체를 생성할 수 있는 템플릿인 클래스를 선언할 수 있습니다.constructor 메서드로 생성자를 정의할 수 있습니다.this 키워드로 인스턴스 객체에 접근할 수 있습니다.new 키워드로 인스턴스 객체를 생성할 수 있습니다.class ClassName {
constructor (value) {
this.property = value;
}
}
let instance = new ClassName("value");
class 표현식으로 선언할 수도 있습니다.NamedClass의 경우 클래스 내부에서만 ClassName에 접근할 수 있습니다.const UnnamedClass = class { ... };
const NamedClass = class ClassName { ... };
extends 키워드를 사용할 수 있습니다.super() 함수를 통해 부모 클래스의 생성자를 호출할 수 있고, 멤버변수나 메서드에 접근할 수 있습니다.static 키워드를 사용해 정적 변수 혹은 정적 메서드를 정의할 수 있습니다.class SuperClass {
constructor () { ... }
static variable = 0;
static method() { ... }
memberMethod() { ... }
}
SuperClass.variable;
SuperClass.method();
class SubClass extends SuperClass {
constructor () {
super(); // super class 생성자 호출
super.method(); // static 메서드 호출
super.memberMethod(); // 메서드 호출
}
}
Promise는 비동기 함수를 호출했을 때 동기 함수처럼 사용하기 위한 자바스크립트 객체입니다.Promise는 pending, fulfilled, rejected 상태 중 하나를 가집니다. pending은 비동기 요청에 대한 응답을 대기하는 상태입니다. 응답을 받았을 때, 성공적으로 완료됐으면 fulfilled 상태로 되고, 실패했으면 rejected 상태가 됩니다. (fulfilled 혹은 rejected된 상태를 통틀어 settled라고 합니다.)pending 상태에서 fulfilled 상태가 되면 then 메서드의 인자로 전달된 함수를 호출합니다. 연산의 결과를 호출된 함수의 첫 번째 인자로 합니다.pending 상태에서 rejected 상태가 되면 catch 메서드의 인자로 전달된 함수를 호출합니다. 에러 내용을 호출된 함수의 첫 번째 인자로 합니다.const promise = new Promise((resolve, reject) => {
if (성공조건) resolve(연산의 결과);
else if (실패조건) reject(에러 내용);
});
promise.then((결과내용) => { /* 결과 처리 */ }).catch((에러내용) => { /* 에러 핸들링 */ });
Symbol(description) 함수는 고유한 Symbol 값을 반환합니다. 객체 프로퍼티에 대한 식별자로 사용될 수 있습니다.Symbol은 Number, String과 같은 원시 데이터 타입이지만, 고유하기 때문에 어느것도 서로 같지 않습니다.description 프로퍼티를 통해 description 매개변수에 접근할 수 있습니다.console.log(Symbol() === Symbol()); // false
console.log(Object.is(Symbol(), Symbol())); // false
const symbol = Symbol(10);
console.log(symbol === 10); // false
console.log(symbol.description); // 10
undefined를 가집니다.undefined가 넘어가도 기본 값으로 설정됩니다.function foo(x, y = 10) {
console.log(x + y);
}
foo(1, 2); // 3
foo(1); // 11
foo(1, undefined); // 11
foo(1, null); // 1
foo(1, 0); // 1
foo(1, ""); // 1 <- String
function foo(...args) {
console.log(Array.isArray(args)); // true
console.log(args); // [1, 2, 3, 4, 5]
}
foo(1, 2, 3, 4, 5);
function bar(a, b, ...args) {
console.log(a, b, args); // 1 2 [3, 4, 5]
}
bar(1, 2, 3, 4, 5);
arguments 객체와는 달리 배열로 받습니다. arguments는 유사배열입니다.arguments는 Symbol.iterator 속성이 있으므로 for...of 반복이 가능하지만, 배열이 아니므로 배열 매서드를 사용할 수 없습니다.function foo() {
console.log(Array.isArray(arguments)); // false
console.log(arguments); // Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
foo(1, 2, 3, 4, 5);
console.log(Math.max(1, 2, 3)); // 3
console.log(Math.max(...[1, 2, 3])); // 3
console.log([1, 2, ...[3, 4, 5], 6, 7]); // [1, 2, 3, 4, 5, 6, 7]
console.log([..."ABC"]); // ["A", "B", "C"]
const obj = {
a: "A",
b: "B"
};
console.log({ c: "C", ...obj }); // {c: "C", a: "A", b: "B"}
const numbers = [1, 2, 3, 4, 5];
let [a, b] = numbers;
console.log(a); // 1
console.log(b); // 2
let [a, b, ...c] = numbers; // rest syntax
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3, 4, 5]
const object = {
a: 10,
b: 20,
c: 30
};
let { a, b, c } = object;
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
${ } 안에 표현식을 작성합니다.const greetings = `
Current Time: ${new Date().getHours()} : ${new Date().getMinutes()}
`;
console.log(greetings);
// <- new line
// Current Time: 17 : 2
function tag(strings, ...args) {
console.log(strings); // ["Current Time: ", " : ", "", raw: ["Current Time: ", " : ", ""]]
console.log(args); // [17, 8]
return "Custom String";
}
const greetings = tag`Current Time: ${new Date().getHours()} : ${new Date().getMinutes()}`
console.log(greetings); // Custom String