js진영의 내용을 전체적으로 알아보는 느낌, 처음 js진영을 학습할 때 부분 부분 깊게 들어가는 것 보다 node.js 교과서
처럼 전체적인 흐름을 학습하고 후에 부분 부분 디테일을 쌓아가는 것이 좋을 것 같다.
var, let, const
ES2015 이상의 문법을 지원하는 환경이면 const, let을 사용하기 권장합니다.
var : 함수 스코프, 호이스팅 O, ~ ES2014
let : 블록 스코프, 호이스팅 X, 변수, ES2015 ~
const : 블록 스코프, 호이스팅 X, 상수, ES2015 ~
if(true) {
var x = 3;
}
console.log(x); // 3
if(true) {
const y = 3;
}
console.log(y); // Uncauht ReferenceError : y us not defined
큰따옴표나 작은따옴표를 사용하여 문자열을 사용하지 않고 백틱('`')을 사용 하는 방식
레거시
var string = num1 + ' 더하기 ' + num2 + '는 \'...'
템플릿 문자열
const string = `${num1} 더하기 ${num2} 는'...`
속성명과 변수명이 동일할 때 더 간단한 문법으로 할당할 수 있음
const sayNode = function() {
console.log('hello');
};
const obj = {
sayJS() { // sayJS라는 멤버명으로 참조한다.
console.log('JS');
},
sayNode, // sayNode라는 멤버명으로 참조한다.
[es6]: 'FANSTASTIC', // 객체 리터럴안에서 선언하고 할당할 수 있음
};
{ name, age } // name, age라는 멤버명으로 참조한다.
(add1, 2, 3, 4), (not1, 2)는 같은 기능을 제공합니다.
기존의 function을 사용하는 방식과의 큰 차이점은 'this binding'입니다.
function add1(x, y) { // 레거시
return x + y;
}
const add2 = (x, y) => {
return x + y;
}
const add3 = (x, y) => x + y;
const add 4 = (x, y) => (x + y);
function not1(x) { // 레거시
return !x;
}
const not2 = x => !x;
arrow, function내에서 this가 참조하는 값이 서로 다르다.
var relationship1 = {
name: 'zero',
friends: ['1', '2', '3'],
logFriends: function() {
var that = this;
this.friends.forEach(function(friends) {
console.log(that.name, friends); // that를 통해 this를 가져온다.
});
}
};
const relationship2 = {
name: 'apple',
friends: ['a', 'b', 'c'],
logFriends() {
this.friends.forEach(friend => {
console.log(this.name, friend); // relationship2의 this를 가져온다.
});
}
};
객체 비구조화
// 레거시 버전
var candyMachine = {
status: {
name: 'node',
count: 5
},
getCandy: function() {
this.status.count--;
return this.status.count;
}
};
var getCandy = candyMachine.getCandy;
var count = candyMachine.status.count;
// 새로운 버전
const candyMachine2 = {
status: {
name: 'node',
count2: 5,
},
getCandy() {
this.status.count--;
return this.status.count;
}
};
const { getCandy2, status: { count2 } } = candyMachine2;
배열 비구조화
// 레거시 버전
var array = ['nodejs', {}, 10, true];
var node = array[0];
var obj = array[1];
var bool = array[array.length - 1];
// 새로운 버전
const array2 = ['nodejs', {}, 10, true];
const [node2, obj2, , bool2] = array2;
console.log(node2, obj2, bool2);
자바스크립트와 노드에서는 주로 비동기 프로그래밍을 자주 한다.
이벤트 주도 방식 때문에 콜백 함수를 자주 사용하며
ES2015부터는 콜백 대신 Promise를 기반으로 사용됩니다.
const condition = true;
const promise = new Promise((resolve, reject) => {
// 성공한 경우 resolve를 호출
// 실패한 경우 reject를 호출
if(condition)
resolve('성공');
else
reject('실패');
});
promise
.then((message) => { // 성공한 경우 실행
console.log(message);
})
.catch((error) => { // 실패한 경우 실행
console.error(error);
});
기존 nested한 callback으로 표현하는 로직이 평평한 형식으로 표현할 수 있음
promise
.then((message) => {
console.log(message);
return new Promise((resolve, reject) => {
resolve(message);
})
})
.then((message2) => {
console.log(message2);
return new Promise((resolve, reject) => {
resolve(message2);
})
})
.then((message3) => {
console.log(message3);
})
.catch((error) => {
console.error(error);
});
2개 이상의 Promise도 쉽게 다룰 수 있다.
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
// 모든 promise가 resolve(성공)해야 then구문으로 접근
Promise.all([promise1, promise2])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
노드 7.6부터 지원되는 기능(ES2017부터 지원합니다.)
콜백 지옥을 프로미스로 탈출하고 async/await으로 한번 더 가독성을 향상시켜붑니다.
Promise 기반 코드
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
Users.findOne({ gender : 'm'});
})
.then((user) => {
// 생략
})
.catch(err => {
console.log(err);
});
}
async/await 기반 코드
// function 방식
async function findAndSaveUser(Users) {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm'});
} catch(error) {
console.log(error);
}
}
// arrow 방식
const findAndSaveUser = async (Users) => {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm'});
} catch(error) {
console.log(error);
}
}
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
for await (promise of [promise1, promise2]) {
console.log(promise);
}
})();