자바 스크립트의 문법에 변화를 가져온 것이 ES2015 혹은 ES6라고 부른다.
매년 문법 변경사항과 새로운 문법상세에 대해 늘 새로워진 것이 나온다.
언제나 변화에 민감하고 변화하는것을 배워야 한다고 생각한다. 이 중 몇개만 살펴보자.
const, let
자바 스크립트에서는 var로 변수를 선언한다. 이제는 const와 let이 대체한다.
var은 함수 스코프를 가지므로 블록 밖의 스코프를 접근할 수 있지만, const와 let은 그럴 수 없다.
const와 let의 차이는 const는 한 번 대입하면 다른 값을 대입할 수 없다. 초기화 시 값을 대입하지 않으면 에러가 발생한다. 그래서 변수 선언시 const를 사용하고 다른 값을 대입할 일이 생긴다면 let을 사용하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<script>
if(true) {
var x = 3;
}
console.log(x);
if(true){
const y=3;
}
console.log(y);
const a=0;
a = 1;
</script>
</head>
<body>
</body>
</html>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by
|
어떤 에러가 발생하는지 크롬 개발자 도구로 테스트해보길 바란다.
템플릿 문자열
새로운 문자열이다. 'tab'키의 위에 있는 `이다. 문자열안에 변수를 넣을 수 있다.
1
2
3
4
5
6
7
|
<script>
const num3 = 1;
const num = 2;
const result = 3;
const string = `${num} 더하기 ${num3}는 '${result}'`;
console.log(string);
</script>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
이 같은 결과를 얻을 수 있다. ${변수}로 이제 '더하기' 기호를 사용하지 않아도 된다.
객체 리터럴
{} 으로 표현하는 것이며, {}안에 함수, 객체, 속성값을 담을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<script>
var sayNode = function(){
console.log('NODE');
}
var es = 'ES';
var oldObjecrt = {
sayJs: function(){
console.log('JS');
},//객체의 메서드에 함수를 연결할 떄
sayNode: sayNode, // 2번 사용한다.
};
oldObjecrt[es+6]='fantastic';
//객체의 속성명
oldObjecrt.sayNode();
console.log(oldObjecrt.ES6);
</script>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<script>
const newObject = {
sayJs(){
console.log('JS');
},
sayNode,
[es+6]:'Fantastic',
};
newObject.sayNode();
console.log(newObject.ES6);
</script>
|
위의 두 코드는 모두 같다. 요약하면 객체의 메서드 연결에 : 과 function을 붙이지 안하도 되고, 속성명과 변수명의 중복을 피해 하나로 표현한다. 그리고 동적으로 객체의 속성명을 설정할 수 있다.
화살표 함수
기존의 funtion() {} 을 화살표로 대체한다.
1
2
3
4
5
6
|
<script>
function add1(x,y){
return x+y;
}
const add2 = (x,y) => x+y;
</script>
|
위 두 함수는 같은 기능을 한다. function 키워드와 return 키워드를 생략하여 나타낼 수 있다.
화살표 함수에서 this함수의 바인딩 방식이 다르다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<script>
var relation1 = {
name : 'zero',
friends : ['nero', 'hero', 'xero'],
logfriend: function(){
var that = this; // relation1을 가리키는 this를 that에 저장
this.friends.forEach(function(friend){
console.log(that.name,friend);
})
}
}
relation1.logfriend();
const relation2 = {
name : 'zero',
friends : ['nero', 'hero', 'xero'],
logfriend(){
this.friends.forEach(friend =>{
console.log(this.name,friend);
});
}
}
relation2.logfriend();
</script>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
위 코드에서 relation1.logfriend()안의 foreach문에서는 function을 사용하여 각자 다른 함수 스코프의 this를 가지므로 that이라는 변수를 사용해 relation1에 간접적으로 접근한다.
relation2.logfriend()안의 foreach문에서는 화살표 함수로 바깥 스코프인 logfriend()의 this를 그대로 사용할 수 있다. 즉 상위 스코프의 this를 그대로 사용할 수 있다. 물론 결과는 두 객체 모두 같다.
비구조화 할당
객체와 배열로부터 속성이나 요소를 쉽게 꺼낼 수 있다. 코드 줄 수를 상당히 줄일 수 있다.
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
|
<script>
var candy = {
status: {
name: 'node',
count: 5,
},
get2:function(){
return this.status.count;
}
};
var gett = candy.get2;
//객체의 속성을 같은 이름의 변수에 대입하는 코드
const candy2 = {
status2:{
name2:'node',
count2: 5,
},
get3(){
this.status2.count2--;
return this.status2.count2;
}
}
const {get3,status2:{count2}} = candy2;
//이같이 candt2 객체 안의 속성을 찾아서 변수와 매칭시킬 수 있다.
</script>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
프로미스(promise)
자바 스크립트와 Node는 비동기 프로그래밍을 진행한다. 이벤트 주도 방식을 통한 콜백 함수를 자주 사용한다. 이 프로미스를 통해 콜백 헬(callback hell)을 극복한다.
- 객체생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<script>
const condition = true;
const promise = new Promise((resolv, reject) =>{
if(condition){
resolv('성공');
}
else {
reject('실패');
}
});
console.log(message); // 성공한 경우 실행
})
.catch((error)=>{
console.error(error); // 실패한 경우 실행
})
</script>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
new Promise로 프로미스 생성, 두 매개변수를 갖는 콜백함수 지정,
promise변수에 then과 catch메서드 사용 가능, resolv가 실행되면 then이 실행, reject면 catch실행
두 매개변수에 넣은 인자는 then과 catch의 매개변수에서 받을 수 있다. 예로 resolv('성공') 호툴되면 then의 message가 '성공'이 된다. condition변수를 false로 바꾸면 반대로 바뀜...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
console.log(message); //
})
.then((message2)=>{
console.log(message2);
return new Promise((resolv,reject)=>{
resolv(message2);
})
});
.then((message3)=>{
console.log(message3);
})
.catch((error)=>{
console.error(error); //
})
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
처음 then에서 message를 resolv하면 다음 then에서 받을 수 있다. 여기서 다시 message2를 resolv했으므로 다음 then에서 message3을 받는다. 이것을 활용해 콜백을 프로미스로 바꿀 수 있다. 예를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function findAndSave(users){
users.findOne({},(err,user)=>{ //첫번째 콜백
if(err){
return console.log(err);
}
user.name = 'zere';
if(err){
return console.error(err);
}
user.findOne({gender: 'm'}, (err,user)=>{ //3번째 콜백
//
});
});
});
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function findAndSave(users){
users.findOne({}).then((user) =>{
user.name2 = 'zero2';
return user.save();
})
.then((user)=>{
return users.findOne({gender2:'m2'});
})
.then((user)=>{
//
})
.catch(err =>{
console.error(err);
});
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
아래코드의 then메서드는 순차적으로 실행된다. 콜백에서 매번 따로 처리해야 하던 에러도 마지막 catch에서 한번에 처리할 수 있다. 메서드가 프로미스 방식을 지원하면 위 코드와 같이 사용할 수 있다.
findOne과 save메서드가 내부적으로 프로미스 객체를 가지고 있어 가능하다.
이외에도 Promise.all 과 Promise.resolve, Promise.reject도 있다.
async/await
노드 7.6 버전부터 지원하는 기능이다. 이것은 프로미스를 사용한 코드를 한번 더 깔끔하게 한다.
위의 promise 코드를 한번 더 바꿀 수 있다.
1
2
3
4
5
6
7
8
|
async function findAndSaveUser(Users){
let user = await Users.findOnd({});
user.name = 'zero';
user = await user.save();
user = await User.findOnd({gender : 'm'});
//
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
함수 선언부에 async function으로 바꾸고 프로미스 앞에 await를 추가하면, 함수는 프로미스가 resolve될 때까지 기다린 다음 로직으로 넘어간다. 예를들어 await Users.findOne({})이 resolve될 때까지 기다린 뒤, user변수를 초기화한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const findAndSaveUser = async (Users) => {
try{
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await User.findOne({gender:'m'});
//
}
catch(error){
console.error(error);
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
위와 같이 try/catch문으로 에러를 처리하는 부분을 만들어준다. 위의 코드는 화살표 함수를 통해 작성하였다.
이제 중첩되는 콜백 함수는 프로미스를 거쳐 async/await 문법으로 사용하는 연습을 한다면 코드가 간결해질 수 있다.
이와 함께 Promise.all 대신 for await of 문을 사용해서 프로미스를 반복 할 수있다.
출처 : 책 - Node.js 교과서
'node.js' 카테고리의 다른 글
[node.js] Express_ Router객체 (0) | 2019.08.24 |
---|---|
[node.js] Express_구조 와 미들웨어 (0) | 2019.08.24 |
[Node.js] NPM 시작하기 (0) | 2019.08.21 |
[Node.js] Node 내장 객체 및 모듈 (0) | 2019.08.21 |
[node.js] 콜백 함수, 프로토타입 (0) | 2019.08.17 |