이번 수업에 들은 ‘모던 자바스크립트 살펴보기’에 대한 내용입니다.
이런 정보를 찾아보며 개발을 한다는 사실이 저에겐 흥미로웠습니다.
모던 자바스크립트 살펴보기
TC39
ECMA Script (= javascript) 의 표준을 재정 하고 update를 관리하는 조직
node.green
Node 버전별 구현된 기능을 확인할 수 있는 페이지
위 ECMA Script 표준 및 Update 진행 중인 기능 들이 어디까지 구현되어 있는지 확인할 수 있음
let, const - ES2015 오픈
hoisting 규칙이 없고, block scoping (block 내 선언된 변수는 block 내에서만 사용) 을 지원함
- let 은 레퍼런스(값이)가 바뀔 수 있고, const 는 바뀔 수 없다 (= final)
- var 와 달리 let 과 const 는 같은 스코프내 같은 변수를 두번 이상 선언할 수 없다. (Syntax Error)
- let 과 const 의 예측 가능성ㅇ과 유지보수성이 var 보다 훨씬 뛰어남
가능하면 const 만 사용하고, 필요시 let 은 사용하나, var 는 절대 사용 하지 마라
let x = 1
x = 2 // Ok
const y = 1
y = 2 // TypeError
var x = 1
var x = 2 // OK
let x = 1
let x = 2 // SyntaxError
console.log(x) // OK
var x = 0
console.log(x) // Error
const x = 0
var x = 1
{
var x = 2
console.log(x) // 2
}
console.log(x) // 2
const x = 1
{
const x = 2
console.log(x) // 2
}
console.log(x) // 1
Spread Syntax - ES2015 오픈
// object merge (1)
const personalData = {
nickname: 'CG',
email: '2carrot84@gmail.com',
}
const publicData = {
age: 22,
}
const user = {
...personalData,
...publicData,
}
console.log(user) // { nickname: 'CG', email: '2carrot84@gmail.com', age: 22 }
// object merge (2)
const overrides = {
DATABASE_HOST: 'myhost.com',
DATABASE_PASSWORD: 'mypassword',
}
const config = {
DATABASE_HOST: 'default.host.com',
DATABASE_PASSWORD: '****',
DATABASE_USERNAME: 'myuser',
...overrides
}
/*{
DATABASE_HOST: 'myhost.com',
DATABASE_PASSWORD: 'mypassword',
DATABASE_USERNAME: 'myuser',
}*/
// object rest
const user = {
nickname: 'CH',
age: 22,
email: '2carrot84@gmail.com'
}
const { nickname, ...personalData } = user // nickname 제외 후 personalData 객체 생성
console.log(personalData) // { age: 22, email: '2carrot84@gmail.com' }
// array merge
const pets = ['dog', 'cat']
const predators = ['wolf', 'cougar']
const animals = [...pets, ...predators]
console.log(animals) // [ 'dog', 'cat', 'wolf', 'cougar' ]
function foo(head, ...rest) {
console.log(head)
console.log(rest)
}
foo(1, 2, 3, 4)
/*
1
[ 2, 3, 4 ]
*/
Promise
비동기 작업 종료 시점의 완료 or 실패와 그 결과 값을 나타냄
미래의 어떤 시점에 결과를 제공하겠다는 약속(Promise)를 반환
Promise 상태
- pending (대기) : 이행하지도, 거부하지도 않은 초기 상태
- fulfuilled (이행) : 연산이 성공적으로 완료
- reject (거절) : 연산 실패
resolve()
주어진 값으로 이행하는 Promise 객체를 반환
지정한 값이 then 메서드를 가지는 경우, Promise.resolve() 가 반환하는 Promise는 then 메서드를 따라가서 자신의 최종 상태를 결정
reject(reason)
주어진 사유로 거부하는 Promise 객체를 반환
then
Promise 에 이행과 거부처리기 콜백을 추가
catch
Promise 에 거부처리기에 콜백을 추가
finally
Promise 에 이행, 거부에 상관 없이 항상 호출
const sleep = (ms) => {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
new Promise((resolve, rejects) => {
console.log('Inside promise')
sleep(1000)
rejects(new Error('First reject'))
resolve('First resolve')
}).then(value => {
console.log('Inside first then')
console.log('value', value)
}).catch(error => {
console.log('error', error)
})
/*
Inside promise
error
:Error: First reject
*/
new Promise((resolve, rejects) => {
console.log('Inside promise')
rejects(new Error('First reject'))
resolve('First resolve')
}).catch(error => {
console.log('error', error)
}).then(value => {
console.log('Inside first then')
console.log('value ', value)
})
/*
Inside promise
error
:Error: First reject
Inside first then
value undefined
*/
new Promise((resolve, rejects) => {
console.log('Inside promise')
setTimeout(() => {
resolve(Math.random())
console.log('After resolve')
}, 1000)
}).then((value) => {
console.log('then 1')
console.log('value :', value)
}).then((value) => {
console.log('then 2')
}).then((value) => {
console.log('then 3')
})
/*
Inside promise
After resolve
then 1
value0.6893501856716817
then 2
then 3
*/
function returnPromiseForTimeout() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.random())
}, 1000)
})
}
returnPromiseForTimeout()
.then(value => {
console.log(value)
return returnPromiseForTimeout()
})
.then(value => {
console.log(value)
return returnPromiseForTimeout()
})
.then(value => {
console.log(value)
return returnPromiseForTimeout()
})
.then(value => {
console.log(value)
return returnPromiseForTimeout()
})
/*
0.8451924276841662
0.3173270175130023
0.2899827674825355
0.8148152584175137
*/
setTimeout(() => {
const value1 = Math.random()
console.log(value1)
setTimeout(() => {
const value2 = Math.random()
console.log(value2)
setTimeout(() => {
const value3 = Math.random()
console.log(value3)
setTimeout(() => {
const value4 = Math.random()
console.log(value4)
}, 1000)
}, 1000)
}, 1000)
}, 1000)
/*
0.8581614552504644
0.3946617212828898
0.8469318628343485
0.7590294478424375
*/
const fs = require('fs')
async function main() {
try {
const result = await fs.promises.readFile('../.gitignore', 'utf-8')
console.log(result)
} catch (e) {
console.log('error', e)
}
}
main()
function readFileInPromise(filename) {
return new Promise((resolve, reject) => {
fs.readFile(filename, 'utf-8', (error, value) => {
if (error) {
reject(error)
}
resolve(value)
})
})
}
readFileInPromise('.gitignore').then(value => console.log(value))
fs.readFile('.gitignore', 'utf-8', (error, value) => {
console.log(value)
})
fs.promises.readFile('../.gitignore', 'utf-8')
.then(value => console.log(value))
async / await
async
비동기 함수를 async 함수로 만들기 위하여 function() 앞에 async 키워드 추가
async 함수는 await 키워드가 비동기ㅣ 코드를 호출할 수 있게 해주는 함수
async 키워드 추가 시 함수는 결과 대신 Promise 를 반환
await
await + async 함수 사용시 장점이 확실
Promise 기반 함수 앞에 놓을 수 있음
- Promise 가 fulfil 될때까지 잠시 중단하고 결과를 반환
- 실행을 기다리는 다른 코드들을 중지 없이 실행
async function sleep(duration) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(undefined)
}, duration)
})
}
async function main() {
console.log('first')
await sleep(1000)
console.log('second')
await sleep(1000)
console.log('third')
await sleep(1000)
console.log('finish!')
}
main()
/*
first
second
third
finish!
*/
마무리
기록을 하고 있지만 돌아서면 까먹는건 집중을 못한 탓일까.. 나이 탓일까.. 🤔😂
그럼 이만. 🥕👋🏼🖐🏼