변경 사항을 중심으로 ES2015 이상의 자바스크립트 문법에 대해 정리한다.
if (true) {var x = 3;}
console.log(x); // 3
if (true) {const y = 3;}
console.log(y); // ReferenceError: y is not defined
const a = 0;
a = 1; //TypeError: Assignment to constant variable
const c; // SyntaxError: Missing initializer in const declaration
const num3 = 1;
const num4 = 2;
const result2 = 3;
console.log(`${num3} 더하기 ${num4}는 ' ${result2}'`); // 1 더하기 2는 '3'
const newObject = {
sayJS() {console.log('JS');}
};
var sayNode = function() {console.log('Node');};
const newObject = {
sayNode
};
newObject.sayJS(); // JS
var es = 'ES'
const newObject = {
[es + 6] : 'Fantastic'
};
console.log(newObject.ES6); // Fantastic
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 not1(x) {return !x;}
const not2 = x => !x ;
var relationship1 = {
name : 'zero',
friends : ['nero', 'hero', 'xero'],
logFriends : function() {
// this는 relationship1을 가리킨다.
var that = this;
// this는 logFriends를 가리킨다.
this.friends.forEach(function(friend){console.log(that.name, friend)});
}
};
const relationship2 = {
name : 'zero',
friends : ['nero', 'hero', 'xero'],
// 두 this 모두 relationship2를 가리킨다.
logFriends() {this.friends.forEach(friend => console.log(this.name, friend))}
};
const candyMachine = {
status : {
name : 'node',
count : 5
},
getCandy() {
this.status.count--;
return this.status.count;
}
};
// candyMachine 객체의 속성을 변수와 매칭, getCandy와 count 변수 초기화
const {getCandy, status : {count}} = candyMachine;
// bind를 사용해 this를 고정
const boundGetCandy = getCandy.bind(candyMachine);
const array = ['nodejs', {}, 10, true];
const [node, obj, , bool] = array;
class Human {
constructor(type = 'human') {
this.type = type;
}
static isHuman(human) {
return human instanceof Human;
}
breathe() {
alert('h-a-a-a-m');
}
}
class Zero extends Human {
constructor(type, firstName, lastName) {
super(type);
this.firstName = firstName;
this.lastName = lastName;
}
sayName() {
super.breathe();
alert(`${this.firstName} ${this.lastName}`);
}
}
const newZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(newZero); // true
① 프로미스의 개념
const condition = true; // true이면 resolve, false이면 reject
const promise = new Promise((resolve, reject) => {
if (condition) {resolve('성공');}
else {reject('실패');}
});
promise
.then((message) => { // 성공(resolve)한 경우 실행
console.log(message); // 성공
})
.catch((error) => { // 실패(reject)한 경우 실행
console.error(error); // 실패
})
.finally(() => {
console.log('무조건'); // 성공, 실패에 관계 없이 실행
});
② then이나 catch에 다른 then이나 catch를 연결할 수 있다.
promise
.then((message) => {
return new Promise((resolve, reject) => {resolve(message);});
})
// 처음 then에서 message를 resolve하면 다음 then에서 message2로 받을 수 있다.
.then((message2) => {
console.log(message2);
return new Promise((resolve, reject) => {resolve(message2);});
})
// 다시 message2를 resolve한 것을 다음 then에서 message3으로 받았다.
// then에서 new Promise를 return해야 다음 then에서 받을 수 있다
.then((message3) => {
console.log(message3);
})
.catch((error) => {
console.error(error);
});
③ 프로미스는 콜백이 여러 번 중첩되는 문제를 해결할 수 있다.
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
return Users.findOne({ gender: 'm' });
})
.then((user) => {
// 생략
})
.catch(err => {
console.error(err);
});
}
④ Promise.all, Promise.resolve, Promise.reject, Promise.allSettled
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
.then((result) => {
console.log(result); // ['성공1', '성공2'];
})
.catch((error) => {
console.error(error);
});
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.reject('실패2');
const promise3 = Promise.resolve('성공3');
Promise.allSettled([promise1, promise2, promise3])
.then((result) => {
console.log(result);
/* [
* { status: 'fulfilled', value: '성공1' },
* { status: 'rejected', reason: '실패2' },
* { status: 'fulfilled', value: '성공3' }
* ]
*/
})
.catch((error) => {
console.error(error);
});
try {
Promise.reject('에러');
} catch (e) {
console.error(e); // UnhandledPromiseRejection: This error originated either by throwing inside...
}
Promise.reject('에러').catch(() => {
// catch 메서드를 붙이면 에러가 발생하지 않음
})
// (1) async funtion으로 함수 선언
async function findAndSaveUser(Users) {
try {
// (2) 프로미스 앞에 await -> 프로미스가 resolve될 때까지 기다린 후 user 변수 초기화
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({gender : 'm'});
// 생략
}
catch (error) {
console.error(error);
}
}
// 화살표 함수로 작성
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.error(error);
}
};
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
for await (promise of [promise1, promise2]) {
console.log(promise);
}
})();
① Map : 객체와 유사한 자료구조로, 속성들 간의 순서를 보장한다.
const m = new Map();
m.set('a', 'b');
m.set(3, 'c');
const d = {};
m.set(d, 'e'); // 객체도 가능
console.log(m.get(d)); // e
console.log(m.size); // 3
for (const [k, v] of m) {console.log(k, v);}
m.forEach((v, k) => {console.log(k, v);});
console.log(m.has(d));
m.delete(d);
m.clear(); // 전부 제거
console.log(m.size); // 0
② Set : 배열과 유사한 자료구조로, 중복을 허용하지 않는다.
const s = new Set();
s.add(1);
s.add(2);
s.add('1');
s.add(1); // 중복이므로 무시된다.
console.log(s.size); // size : 3
console.log(s.has(1)); // 존재 여부 : true
for (const a of s) {console.log(a);} // 1 2 '1'
s.forEach((a) => {console.log(a);}) // 1 2 '1'
s.delete(2); // delete()로 요소 2 제거
s.clear(); // clear()로 모든 요소 제거
const arr = [1, 3, 2, 7, 2, 6, 3, 5];
const s = new Set(arr); // 배열의 중복 요소 제거
const result = Array.from(s); // set을 배열로 되돌리기
console.log(result); // 1, 3, 2, 5, 7
① 널 병합 (nullish coalescing) ?? 연산자
const a = 0;
const b = a || 3;
console.log(b); // 3
const c = 0;
const d = c ?? 3; // ?? 연산자는 null과 undefined일 때만 뒤로 넘어감
console.log(d); // 0;
const e = null;
const f = e ?? 3;
console.log(f); // 3;
const g = undefined;
const h = g ?? 3;
console.log(h); // 3;
② 옵셔널 체이닝 (optional chaining) ?. 연산자
const a = {};
a.b; // a가 객체이므로 문제 없다.
const c = null;
try {
c.d;
} catch (e) {
console.error(e); // TypeError: Cannot read properties of null
}
c?.d; // 문제 없음
try {
c.f();
} catch (e) {
console.error(e); // TypeError: Cannot read properties of null
}
c?.f(); // 문제 없음. 객체 뿐만 아니라 함수도
try {
c[0];
} catch (e) {
console.error(e); // TypeError: Cannot read properties of nul
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const result = await axios.get('https://www.zerocho.com/api/get');
console.log(result);
console.log(result.data); // {}
} catch (error) {
console.error(error);
}
})();
</script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
(async () => {
try {
const result = await axios.post('https://www.zerocho.com/api/post/json', {
name: 'zerocho',
birth: 1994,
});
console.log(result);
console.log(result.data);
} catch (error) {
console.error(error);
}
})();
</script>
const formData = new FormData();
formData.append('name', 'zerocho');
formData.append('item', 'orange');
formData.append('item', 'melon');
formData.has('item'); // true
formData.has('money'); // false;
formData.get('item'); // orange
formData.getAll('item'); // ['orange', 'melon'];
formData.append('test', ['hi', 'zero']);
formData.get('test'); // hi, zero
formData.delete('test');
formData.get('test'); // null
formData.set('item', 'apple');
formData.getAll('item'); // ['apple'];
(async () => {
try {
const formData = new FormData();
formData.append('name', 'zerocho');
formData.append('birth', 1994);
const result = await axios.post('<https://www.zerocho.com/api/post/formdata>', formData);
console.log(result);
console.log(result.data);
} catch (error) {
console.error(error);
}
})();
(async () => {
try {
const result = await axios.get(`https://www.zerocho.com/api/search/${encodeURIComponent('노드')}`);
console.log(result);
console.log(result.data); // {}
} catch (error) {
console.error(error);
}
})();
decodeURIComponent('%EB%85%B8%EB%93%9C'); // 노드
<ul>
<li data-id="1" data-user-job="programmer">Zero</li>
<li data-id="2" data-user-job="designer">Nero</li>
<li data-id="3" data-user-job="programmer">Hero</li>
<li data-id="4" data-user-job="ceo">Kero</li>
</ul>
<script>
// li 태그의 data-id와 data-user-job에 접근
console.log(document.querySelector('li').dataset);
// { id: '1', userJob: 'programmer' }
</script>
const relationship = {
name : 'zero',
friends : ['nero', 'hero', 'xero'],
logFriends() {this.friends.forEach(friend => console.log(this.name, friend))}
};
const c = 0;
const d = c ?? 3;
console.log(d); // 코드 1
const e = null;
const f = e ?? 3;
console.log(f); // 코드 2
const chocoMachine = {
status : {
name : 'node',
count : 5
},
getChoco() {
this.status.count--;
return this.status.count;
}
};
const arr = [1, 3, 2, 7, 2, 6, 3, 5];
// 배열의 중복 요소 제거
const s = ______
// set을 배열로 되돌리기
const result = _______
정답
1. relationship, relationship
2. Promise.all, Promise.allSettled
3. await
4. null, undefined
5. 0, 3
6. AJAX
1번
const {getChoco, status : {count}} = chocoMachine;
2번
const arr = [1, 3, 2, 7, 2, 6, 3, 5];
// 배열의 중복 요소 제거
const s = new Set(arr);
// set을 배열로 되돌리기
const result = Array.from(s);
출처 : 조현영, 『 Node.js 교과서 개정 3판』, 길벗(2022)
Corner Node.js 1
Editor : Snoopy
[노드 1팀] 3장. 노드 기능 알아보기 (2) (0) | 2024.11.08 |
---|---|
[노드 1팀] 3장. 노드 기능 알아보기 (1) (0) | 2024.10.11 |
[노드 1팀] 1장. 노드 시작하기 (0) | 2024.10.11 |
[노드 1팀] 2주차. JavaScript 반복문(Loop), 반복자(Iterator), 객체(Object) (2) | 2024.10.04 |
[노드 1팀] 1주차. JavaScript 조건문(conditionals), 함수(functions), 배열(array) (0) | 2024.10.04 |