JavaScript 언어의 표준이며 ES6라고도 칭한다.
let
을 이용한 변수 선언은 Block Scope 내에 변수를 선언한다. (Block Scope란, 중괄호를 이용하여 구분된 영역이다.)
function varTest() {
var x = 31;
if (true) {
var x = 71; // same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // different variable
console.log(x); // 71
}
console.log(x); // 31
}
const
를 이용하여 선언한 변수는 let
을 이용하여 선언한 변수와 거의 동일하지만 재할당(수정)을 할 수 없다.
const MY_NUMBER = 1;
MY_NUMBER = 2; // Assignment Error
const MY_NUMBER = 2; // Declare Erro
배열이나 객체의 속성을 분해하여 그 값을 개별 변수에 담을 수 있게 하는 표현식이다.
var obj = {
e: 'Eeee',
f: {
g: 'Gee'
}
};
var e = obj.e; // 'Eeee'
var g = obj.f.g; // 'Gee'
기존의 문법은 위와 같이 객체의 값들을 변수로 만들고 있지만 ES2015에서는 아래와 같이 할 수 있다.
const obj2 = {
h: 'Eich',
i: {
j: 'Jay'
}
}
const { h, i: { j }, k } = obj2;
console.log(h, j, k); // 'Eich', 'Jay', undefined
h
변수 값을 자동으로 obj
에서 찾아 넣어주고, j
값도 obj2
안의 i
객체에서 찾아 넣어줌으로써 한 줄의 코드로 객체를 해체해버리는 것이다.
또한 위의 k
처럼 obj2
에 없는 변수를 선언했을 경우, 자동으로 undefined
값이 들어가기 때문에 에러가 발생하지 않는다.
default parameter
는 함수에 전달된 parameter의 값이 undefined
이거나 전달된 값이 없을 때, 초기화 설정된 값을 말한다.
function logName (name = 'surim') {
console.log(name);
}
logName(); // surim
logName('son'); // son
function logNumber (num = 666) {
console.log(num);
}
logNumber(); // 666
logNumber(100); // 100
logNumber(0); // 0
function getNumber () {
console.log('Getting number..');
return 666;
}
function logNumber (num = getNumber()) {
console.log(num);
}
logNumber(); // Getting number, 666
logNumber(undefined); // Getting number, 666
logNumber(null); // null, undefined
logNumber(false); // false, undefined
logNumber(1000); // 1000, undefined
정해지지 않은 수의 인자를 배열로 나타낼 수 있게 한다.
parameter앞에 ...을 붙인다.
function foo(...rest) {
console.log(Array.isArray(rest)); // true
console.log(rest); // [ 1, 2, 3, 4, 5 ]
}
foo(1, 2, 3, 4, 5);
function foo(param1, param2, ...rest){~~} 처럼 앞에 parameter는 일반적인 parameter로 받을 수 있고 그 뒤부터는 Rest parameter로 받을 수 있다.
단, Rest parameter 항상 제일 마지막 parameter로 있어야 한다. (예를들어 function foo(...rest, param1, param2){~}는 사용 불가능하다.)
// Example #1
function foo (a, b, ...c) {
console.log(c); // ["c", "d", "e", "f"]
console.log(Array.isArray(c)); // true
}
foo('a', 'b', 'c', 'd', 'e', 'f');
// "arguments" is different
function foo2 (a, b, ...c) {
console.log(arguments);
console.log(Array.isArray(arguments)); // false
}
foo2(1, 2, 3, 4, 5);
배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인자 또는 요소로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다.
Spread 연산자는 연산자의 대상 배열 또는 이터러블(iterable)을 개별 요소로 분리한다.
// 배열
console.log(...[1, 2, 3]); // -> 1, 2, 3
// 문자열
console.log(...'Helllo'); // H e l l l o
// Map과 Set
console.log(...new Map([['a', '1'], ['b', '2']])); // [ 'a', '1' ] [ 'b', '2' ]
console.log(...new Set([1, 2, 3])); // 1 2 3
// ES6
function foo(x, y, z) {
console.log(x); // 1
console.log(y); // 2
console.log(z); // 3
}
const arr = [1, 2, 3];
foo(...arr);// Array를 받아서 각 매개변수로 전달되었다.
//ES5
var arr = [1, 2, 3];
console.log(arr.concat([4, 5, 6])); // [ 1, 2, 3, 4, 5, 6 ]
// ES6
const arr = [1, 2, 3];
// ...arr은 [1, 2, 3]을 개별 요소로 분리한다
console.log([...arr, 4, 5, 6]); // [ 1, 2, 3, 4, 5, 6 ]
concat() 대신 가독성이 더 좋아지는 것을 볼 수 있다.
const o1 = { x: 1, y: 2 };
const o2 = { ...o1, z: 3 };
console.log(o2); // { x: 1, y: 2, z: 3 }
const target = { x: 1, y: 2 };
const source = { z: 3 };
// Object.assign를 사용하여도 동일한 작업을 할 수 있다.
// Object.assign은 타깃 객체를 반환한다
console.log(Object.assign(target, source)); // { x: 1, y: 2, z: 3 }
출처: https://jeong-pro.tistory.com/117 [기본기를 쌓는 정아마추어 코딩블로그]
//Rest
function foo(param, ...rest) {
console.log(param); // 1
console.log(rest); // [ 2, 3 ]
}
foo(1, 2, 3);
//Spread호출
function bar(x, y, z) {
console.log(x); // 1
console.log(y); // 2
console.log(z); // 3
}
bar(...[1, 2, 3]);
Rest에서는 선언에서 Spread연산자를 제일 뒤에 사용해야 하지만, Spread호출에서는 중간중간 사용해도 상관없다.
var arr1 = [ 1, 2, 3 ];
var arr2 = [ 4, 5, 6 ];
var total = [ ...arr1, ...arr2 ];
console.log(total); // (6) [1, 2, 3, 4, 5, 6]
function foo (a, b, c) {
return a + b + c;
}
foo(...[ 1, 2, 3 ]); // 6
// ES5
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
// apply 메소드의 2번째 인자는 배열. 이것은 개별 인자로 push 메소드에 전달된다.
//Array.prototype.push.apply(arr1, arr2);
//arr1.push(arr2); => [1,2,3,[4,5,6]]
console.log(arr1); // [ 1, 2, 3, 4, 5, 6 ]
// ES6
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// ...arr2는 [4, 5, 6]을 개별 요소로 분리한다
arr1.push(...arr2); // == arr1.push(4, 5, 6);
console.log(arr1); // [ 1, 2, 3, 4, 5, 6 ]
const fn = (a) => {
console.log(a);
};
fn();
const fn = a => {
console.log(a);
};
const multiply = (a, b) => a * b;
const name = 'ni';
function school (code) {
return {
name: 'ken ' + code,
logName: () => {
console.log(this.name);
console.log(arguments);
}
};
}
const obj = school(378);
obj.logName(1,2,3);
// Arrow functions do not have its own`this`, `arguments`.
function onInit () {
const $el = document.querySelector('.target');
$el.addEventListener('click', ev => {
this.textContent = 'hello';
});
}
const myController = {
appName: 'VC',
onInit: onInit
};
myController.onInit();
ES6부터 class
가 도입되었으며 class
는 함수이기 때문에 class문법도 함수와 마찬가지로 class 표현식과 class 선언 두 가지 방법을 제공한다.
class MyClass {} // Class 선언
let MyClass = class {} // Class 표현식
function Car (brand, owner) {
this.brand = brand;
this.owner = owner;
}
Car.prototype.sell = function (newOwner) {
this.owner = newOwner;
};
const car = new Car('Kia', 'Ken');
car.sell('wan');
class Car {
constructor(brand, owner) {
this.brand = brand;
this.owner = owner;
}
sell(newOwner) {
this.owner = newOwner;
}
}
const car = new Car('Kia', 'Ken');
car.sell('wan');
var p = new Polygon(); // ReferenceError
class Polygon {}
Class를 이용하여 선언하더라도 Prototype의 개념은 동일하게 유지된다.
Class란 단순히 Syntax적인 표현일 뿐, 다른 언어의 Class와는 명백히 다르게 작동하므로 유의해야 한다.
''
또는 ""
대신 ``(백틱)이라는 문자열 템플릿이 생겨났다.
console.log('string text line 1
string text line 2'); // Error
console.log(`string text line 1
string text line 2`); // OK
기존의 문자열 템플릿으로 할 경우 발생하는 에러를 백틱으로 변경할 경우 정상으로 작동되는 것을 볼 수 있다.
let name = "Taesu Hyeon";
console.log("My name is " + name); // My name is Taesu Hyeon
위의 코드를 백틱을 사용하여 바꾸어 보았다.
let name = "Taesu Hyeon";
console.log(`My name is ${name}`); // My name is Taesu Hyeon
기존의 템플릿으로 문자열과 변수를 같이 사용할 경우 매번 ""
(따옴표)를 닫은 뒤,+
연산자를 사용하여 가독성이 떨어졌지만 백틱을 사용하여 한 줄에 나타냄으로 가독성이 향상되는 것을 볼 수 있다.
import name from "module-name"; // export default로 export한 멤버를 name에 받음.
import * as name from "module-name"; // export되는 모든 멤버를 name에 받음.
import { member } from "module-name"; // export된 멤버 member를 member로 받음.
import { member as alias } from "module-name"; // export된 멤버 member를 alias로 받음.
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as alias from "module-name";
import defaultMember from "module-name";
import "module-name"; // import만 하면 되는 경우 ex) import "main.css";
default export
의 경우, 모듈 당 딱 하나의 default export가 있으며 default export는 함수 또는 클래스, 오브젝트, 혹은 다른 것들이 될 수 있다. 이값은 가장 간단하게 import 할 수 있도록 하기 때문에 내보낼 값 중 메인에 해당하는 값으로 고려해야한다.
export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // 또는 var
export let name1 = …, name2 = …, …, nameN; // 또는 var, const
export default expression;
export default function (…) { … } // 또는 class, function*
export default function name1(…) { … } // 또는 class, function*
export { name1 as default, … };
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
var arrayOne = [2];
var arrayTwo = [1].concat(arrayOne, [3]); // ES5
var arrayTwo = [1, ...arrayOne, 3]; // ES6
console.log(arrayTwo); // [1, 2, 3]
let objOne = { one: 1 };
let objTwo = Object.assign({}, objOne); // ES5
let objTwo = { ...objOne, two: 2 }; // ES6
console.log(objTwo); // Object {one: 1, two: 2}