[JS] ES5와 ES6 뭐가 다를까?

ES5와 ES6를 비교 할겸
ES6를 사용할때 자주 쓰이는 부분만 정리해보았습니다.

Const 변수

Immutable varibale인 Const 변수(상수 변수)를 지원합니다.(블록-스코프 변수)

1
2
const PI = 3.141592
console.log(PI) // 3.141592

let 변수

기존의 함수-스코프였던 변수와 다르게 Hoisting 없는 블록-스코프 변수를 지원합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// ES5
console.log('for loop start')
for(var i=0; i<10; i++) {
console.log('i : ' + i)
}
console.log('for loop end i : ' + i) // for loop end i : 10

function counter() {
for(var j=0; j<10; j++) {
console.log('j : ', j)
}
}
counter()
console.log('j : ', j) // j is not defined

// ES6
console.log('for loop start')
for(let i=0; i<10; i++) {
console.log('i : ' + i)
}
console.log('for loop end i : ' + i) // j is not defined

function counter() {
for(let j=0; j<10; j++) {
console.log('j : ', j)
}
}
counter()
console.log('j : ',j) // j is not defined

또한 var 변수는 재선언,재할당이 가능하지만 let 변수는 재선언이 불가능합니다 (const 변수는 immutable variable이므로 재할당도 불가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var a = 'foo'
var a = 'bar'

// hoisting으로 ReferenceError가 나지않는다.
b = 'foo'
var b

let c = 'foo'
let c = 'bar' // Uncaught SyntaxError: Identifier 'c' has already been declared
c = 'bar' // "bar"

const d = 'foo'
const d = 'bar' // Uncaught SyntaxError: Identifier 'd' has already been declared
d = 'bar' // Uncaught TypeError: Assignment to constant variable.

Block-Scoped 함수

블록-스코프 함수 정의 방식 개선

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ES6
{
function foo () { return 1 }
console.log(foo()) // 1
{
function foo() { return 2 }
console.log(foo()) // 2
}
console.log(foo()) // 1
}
// ES5
(function () {
var foo = function () { return 1;}
foo() === 1;
(function () {
var foo = function () { return 2; }
foo() === 2;
})();
foo() === 1;
})();

Arrow Function

functionreturn을 묶어 화살표 함수로 변형 가능합니다

1
2
3
4
5
6
7
8
9
10
11
12
13
// ES6
nums = evens.map((v,i) => v+i)
this.nums.forEach((v) => {
if(v % 2 === 0)
this.evens.push(v)
})
// ES5
nums = evens.map(function (v, i) { return v+i; });
var self = this;
this.nums.forEach(function (v) {
if(v % 2 === 0)
self.evens.push(v);
});

디폴트 파라미터

타 언어에서 사용 할 수 있었던 디폴트 파라미터가 지원됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ES6
function foo (x, y=2, z=3) {
return x + y + z
}
foo(1) // 6

// ES5
function foo (x, y, z) {
if(y === undefined)
y = 2;
if(z === undefined)
z = 3;
return x + y + z;
};
foo(1); // 6

Rest Parameter

지정되지 않은 매개변수 집합을 하나의 변수에 담을 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
// ES6
function foo (x, y, ...a) {
return (x * y) + a.length
}
foo(1, 2, "baz", true , 3, [2]) // 6

// ES5
function foo (x,y) {
var a = Array.prototype.slice.call(arguments, 2);
return (x * y) + a.length;
};
foo(1, 2, "baz", true , 3, [2]); // 6

Spread Operator (전개연산자)

2개 이상의 인수나 2개이상의 요소 또는 2개이상의 변수가 해당되는 곳에 확장 될 수 있도록 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
function myFunc(x, y, z){}
// ES6
let params = [ "Foo", true, 2 ]
let others = [ 1, 2, ...params ] // [ 1, 2, "Foo" ,true, 2 ]
let str = "Bar"
let chars = [ ...str ] // [ "B", "a", "r"]
myFunc(1, 2, ...params);
// ES5
var params = [ "Foo", true, 2 ];
var others = [ 1, 2 ].concat(params); // [ 1, 2, "Foo" ,true, 2 ]
var str = "Bar";
var chars = str.split(""); // [ "B", "a", "r"]
myFunc.apply(null, [1, 2].concat(params));

Template Literals

문자열 다중 행 처리와 보간문자 처리를 할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ES6
let user = { name : "Foo" }
let info = { id: "bar", email: "Foo@example.com"}
let userInfo = `Hello ${user.name}.
Your ID is ${info.id}
and email is ${info.email}.`
// Hello Foo.
// Your ID is bar
// and email is Foo@example.com

// ES5
var user = { name : "Foo" }
var info = { id: "bar", email: "Foo@example.com"}
var userInfo = "Hello " + user.name + ".\n"+
"Your ID is " + info.id + "\n"
"and email is "+info.email+".";

Enhanced Object Properties

Property Shorthand

공통 객체 속성 정의를 간결하게 할 수 있습니다.

1
2
3
4
5
6
7
// ES6
let x = 0, y = 0
obj = {x, y}

// ES5
var x = 0, y = 0;
obj = {x: x , y: y};
Computed Property Names

Object 프로퍼티 정의에 계산된 이름을 지원합니다

1
2
3
4
5
6
7
8
9
10
11
// ES6
let obj = {
foo: "Bar",
["Baz" + myFunc() ]: 42
}

// ES5
var obj = {
foo: "Bar"
};
obj["Baz" + myFunc() ] = 42;
Method Properties

일반적인 함수와 제너레이터 함수의 Object 프로퍼티 정의에 메소드를 표기할 수 있도록 지원합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// ES6
obj = {
foo (a, b) {},
bar (x ,y) {},
*baz (x, y) {}
}

// ES5
obj = {
foo: function (a, b) {},
bar : function (x, y) {},
// baz : es5에서는 대체할 것이 없습니다.
}

Export / Import

값을 export/import로 모듈에 가져오거나 모듈로 내보낼 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ES6

// lib/math.js
export function sum (x ,y) { return x + y }
export var pi = 3.141592
// Foo.js
import * as math from "lib/math"
console.log("2pi = " + math.sum(math.pi, math.pi))
// Bar.js
import { sum, pi } from "lib/math"
console.log("2pi = " + sum(pi,pi))

//ES5
// lib/math.js
LibMath = {};
LibMath.sum = function (x ,y) { return x + y };
LibMath.pi = 3.141592;
// Foo.js
var math = LibMath;
console.log("2pi = " + math.sum(math.pi, math.pi));
// Bar.js
var sum = LibMath.sum, pi = LibMath.pi;
console.log("2pi = " + sum(pi,pi));

Class Definition

클래스를 지원합니다 (이외에도 상속, 오버로딩, 정적 클래스멤버, Getter/Setter를 지원합니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ES6
class Car {
constuctor (id, x ,y) {
this.id = id
this.move(x,y)
}
move (x, y) {
this.x = x
this.y = y
}
}

// ES5
var Car = function (id, x ,y) {
this.id = id;
this.move(x, y);
};
Car.prototype.move = function (x, y) {
this.x = x;
this.y = y;
}

Promise

비동기 처리 이후 동작을 순차적,또는 병렬로 진행하기 위해 사용하는 클래스. 기존 Callback Hell에서 벗어날 수 있도록 도와줍니다(잘 구현 했을 경우….)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// ES6
let _promise = () => {
return new Promise((resolve,reject) => {
if(success){
resolve(value) // success
} else {
reject(reason) // fail
}
})
}
_promise()
.then(
(res) => {
//success일때 처리
console.log(res)
},
(err) => {
//reject 일때 처리
console.error(err)
}
)
_promise()
.then(...)
.catch((err) => {
console.error(err)
})

여러개의 프로미스가 모두 완료 될때 실행하려면요?

Promise-all 을 이용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
let _promise1 = new Promise((resolve,reject) => {
if(success){
resolve(value) // success
} else {
reject(reason) // fail
}
})
let _promise2 = new Promise((resolve,reject) => {
if(success){
resolve(value) // success
} else {
reject(reason) // fail
}
})

Promise.all([_promise1, _promise2]).then(
(res) => {
// resolve 된 결과 처리
console.log(res)
},
(err) => {
// reject 된 결과 처리
console.log(err)
}
)

// OR

let _promise1 = () => {
return new Promise((resolve,reject) => {
if(success){
resolve(value) // success
} else {
reject(reason) // fail
}
})
}
let _promise2 = () => {
return new Promise((resolve,reject) => {
if(success){
resolve(value) // success
} else {
reject(reason) // fail
}
})
}

Promise.all([_promise1(), _promise2()]).then(
(res) => {
// resolve 된 결과 처리
console.log(res)
},
(err) => {
// reject 된 결과 처리
console.log(err)
}
)

참고자료

[JS] ES5와 ES6 뭐가 다를까?

https://blog.hodory.dev/2018/04/16/es5-vs-es6/

Author

Hodory

Posted on

2018-04-17

Updated on

2022-08-11

Licensed under

댓글