[Javascript] Node js 기초 2장
- -
node js는 공식 홈페이지에서 다운로드가 가능하다.
https://nodejs.org/ko/download
다운로드 | Node.js
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs.org
1. ES2015+
ES2015+는 자바스크립트 문법이다. 2015년에 자바스크립트 문법에 큰 변화가 있었는데 어떤 식으로 변화되었는지 같이 알아보자.
1.1 const, let
보통 javascript는 var로 변수를 선언한다. 하지만 ES2015+부터는 const와 let가 추가되었다.
if(true) {
var a = 1;
}
console.log(a);
if(true) {
let b = 2;
}
console.log(b); // ERROR
if(true) {
const c = 3;
}
console.log(c); // ERROR
var는 변수를 선언하면 선언한 변수를 나중에 초기값을 설정할 수도 있고 변수의 값을 변경할 수도 있다. 그리고 함수 스코프를 가지므로 블록과 관계없이 접근할 수 있다.
하지만 const와 let는 블록 스코프를 가진다. 그래서 블록 밖에서는 접근할 수가 없다.
또 var로 선언한 변수는 재할당이 가능하고 초기값은 선언안해줘도 된다.
const a = 0;
a = 1; // ERROR
let b = 0;
b = 1;
const c; // ERROR
하지만 const는 변수를 선언하는 동시에 초기값을 설정해줘야 하며 재할당도 불가능하다. 그래서 흔히 const는 상수라고도 표현하기도 한다.
let은 초기값을 설정해도 재할당이 가능하다.
1.2 탬플릿 문자열
ES2015+ 문법에 백틱이 추가되었습니다.
var x = 1;
var y = 2;
var result = x + y;
var string = x + " + " + y + " = " + result
console.log(string);
// 1 + 2 = 3
기존 문법 같은 경우는 문자열을 일일히 더해서 string을 만든다.
const x = 1;
const y = 2;
const result = x + y;
const string = `${x} + ${y} = ${result}`;
console.log(string);
// 1 + 2 = 3
ES2015+ 문법에는 ``으로 문자열을 감싸서 훨씬 깔끔하게 결과를 출력할 수 있다. 그리고 변수를 출력할 때는 ${변수}로 변수 값을 삽입할 수 있다.
1.3 객체 리터럴
객체 리터럴에 편리한 기능들이 추가되었다.
var hack = function() {
console.log("I'm hacker");
};
var rh = 'RH';
var oldObject = {
hello: function() {
console.log("world");
},
hack: hack,
}
oldObject[rh + 1] = '3nu5';
oldObject.hack();
oldObject.hello();
console.log(oldObject.RH1);
let hack = function() {
console.log("I'm hacker");
};
var rh = 'RH';
const newObject = {
hello() {
console.log("world");
},
hack,
[rh + 1]: '3nu5',
}
newObject.hack();
newObject.hello();
console.log(newObject.RH1);
위와 아래 코드를 비교하면 이제 객체의 메서드에 함수를 연결할 때 콜론과 function을 붙이지 않아도 된다.
그리고 {name: name, age: age} 같이 속성과 변수가 동일한 경우 한 번만 써도 된다.
1.4 화살표 함수
화살표 함수라는 새로운 개념이 생겼다.
function add1(x, y) {
return x + y;
}
const add2 = (x, y) => {
return x + y;
}
const add3 = (x, y) => x + y;
const add4 = (x, y) => (x, y);
이렇게 function을 화살표 함수로 간략하게 만들 수 있다. 또한 내부에 return문 밖에 없는 경우는 return 할 값만 작성하면 된다.
1.5 구조분해 할당
구조분해 할당을 사용하면 객체와 배열로부터 속성이나 요소를 쉽게 꺼낼 수 있다.
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 candyMachine = {
status: {
name: 'node',
count: 5,
},
getCandy() {
this.status.count--;
return this.status.count;
},
};
const { getCandy, status: {count} } = candyMachine;
위 코드를 아래로 변경할 수 있다.
코드의 의미는 candyMachine 객체 안의 속성을 찾아서 변수와 매칭한다.
1.6 클래스
클래스 문법이 추가되었는데 다른 언어처럼 클래스 기반으로 동작하는 것이 아니라 프로토타입 기반으로 동작한다.
var Family = function(type) {
this.type = type || 'family';
};
Family.myfamily = function(family) {
return family instanceof Family;
}
Family.prototype.hello = function() {
console.log('world');
};
var Rh = function(type, name, job) {
Family.apply(this, arguments);
this.name = name;
this.job = job;
};
Rh.prototype = Object.create(Family.prototype);
Rh.prototype.constructor = Rh;
Rh.prototype.profile = function() {
console.log(this.name + ' ' + this.job);
}
var person = new Rh('family', 'rhenus', 'hacker');
console.log(Family.myfamily(person));
class Family {
constructor(type = 'family') {
this.type = type;
}
static myfamily(family) {
return family instanceof Family;
}
hello() {
console.log('world');
}
}
class Rh extends Family {
constructor(type, name, job) {
super(type);
this.name = name;
this.job = job;
}
profile() {
super.hello();
console.log(`${this.name}, ${this.job}`);
}
}
const person = new Rh('family', 'rheus', 'hacker');
console.log(Family.myfamily(person));
1.7 프로미스
자바스크립트와 노드에서는 주로 비동기를 많이 사용한다. 특히 이벤트 리스너를 사용할 때 콜백 함수를 자주 사용한다.
ES2015+에서는 자바스크립트와 노드의 API들이 콜백 대신 프로미스기반으로 재구성되고 있다.
그만큼 프로미스는 반드시 알아두어야 하는 객체이다.
프로미스는 다음과 같은 규칙이 있다.
★ 프로미스 객체 생성
const condition = true;
const promise = new Promise((resolve, reject) => { // true일 경우 resolve false일 경우 reject
if(condition) {
resolve("success");
}
else {
reject("fail");
}
});
promise
.then((message) => {
console.log(message); // resolve일 경우 실행
})
.catch((error) => {
console.error(error); // reject일 경우 실행
})
.finally(() => {
console.log("default"); // 무조건 실행
});
new Promise로 프로미스를 생성할 수 있으며 내부에 resolve와 reject를 매개변수로 갖는 콜백 함수를 넣는다.
그래서 프로미스 내부에 resolve가 호출되면 then이 reject가 호출되면 catch가 실행된다. finally는 성공/실패 여부 상관없이 실행된다.
프로미스를 간단하게 설명하면 실행을 바로 하되 결괏값은 나중에 받는 객체이다.
new Promise는 바로 실행이 되지만 결과값은 then을 붙였을 때 받게 된다.
function findAndSaveUser(Users) {
Users.findOne({}, (err, user) => {
if(err) {
return console.error(err);
}
user.name = 'rhenus';
user.save((err) => {
if(err) {
return console.error(err);
}
Users.findOne({job: 'hacker'}, (err, user) => {
//
});
});
});
}
코드를 보면 콜백 함수가 3번 중쳡된다. 그럼 콜백 함수가 나올 때마다 에러도 따로 처리해줘야 하고 코드도 복잡해진다.
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'rhenus';
return user.save();
})
.then((user) => {
return Users.findOne({job: 'hacker'});
})
.then((user) => {
})
.catch(err => {
console.error(err);
});
}
그래서 findOne()함수와 save() 함수가 내부적으로 프로미스가 구현돼있다고 가정하에 위 코드처럼 간단하게 만들 수 있다.
1.8 async/await
async/await 문법으로 인하여 프로미스를 사용한 코드를 한 번 더 깔끔하게 줄일 수 있다.
async function findAndSaveUser(Users) {
let user = await Users.findOne({});
user.name = 'rhenus';
user = await user.save();
user = await Users.findOne({ job: 'hacker' });
//
}
위의 프로미스 코드를 async/await로 줄였다. async function는 해당 프로미스가 resolve 될 때까지 기다린 뒤 다음 로직으로 넘어간다. 그래서 await Users.findOne({})이 resolve가 되면 user 변수를 초기화한다. 그런데 해당 코드는 에러를 처리하는 부분이 없어서 try/catch문을 추가해야 한다.
다음 장에서는 노드 기능을 알아보자.
'Language > Javascript' 카테고리의 다른 글
[Javascript] Node js 기초 3장 (0) | 2023.08.24 |
---|---|
[Javascrpit] Node js 기초 1장 (0) | 2023.08.20 |
소중한 공감 감사합니다