Javascript 개발 경험이 없는 사람이 JS로 쓰인 프로젝트를 빠르게 이해하기 위해서 필요했던 내용을 간단하게 정리한 글이다.
마지막 업데이트: 2023-08-12
Equality는 두 피연산자의 타입이 다를 경우 타입 변환을 시도해 값을 비교한다. Strict Equality는 타입 변환을 하지 않는다.
1 == new Number(1) // true, Number을 원시 객체로 변환
1 === new Number(1) // false
1 == true // true, boolean을 number로 변환
1 === true // false
1 == '1' // true, 문자열을 number로 변환
1 === '1' // false
Optional chaining은 참조하려는 객체가 Nullish(undefined이거나 null)이면 error를 던지지 않고 short circuit으로 undefined를 반환한다.
const person = {
name: string;
}
person?.age; // valid, return undefined
person?.age?.myFunc1()?.myFunc2(); // return undefined from person?.age
Nullish coalescing operator은 좌항이 Nullish이면 우항을 반환하고, 그렇지 않으면 좌항을 반환한다.
const foo = null ?? 'default'; // return 'default'
cf) TypeScript optional property (?)
Typescript의 property가 optional임을 표시하려면 property name에 '?'를 붙인다.
type Person = {
name: string;
age?: number;
}
let person: Person = {
name: "abc";,
} // valid
값을 할당하지 않은 optional field를 참조하면 undefined를 반환한다. 반대로 optional field에 undefined를 assign 할 수 있다.
Promise는 비동기 작업의 return value를 나타낸다. 비동기 작업의 성공 여부에 따라서 promise를 매개변수로 하는 함수를 호출할 수 있다.
let testPromise = new Promise((resolve, reject) => {
const response = sendServerRequest();
if(response.status === 'SUCCESS') {
resolve(response);
} else {
reject(response):
}
});
testPromise.then((response) => { // 비동기 함수에서 resolve()를 호출할 때 실행
console.log('SUCCESS');
console.log(JSON.stringify(response.data));
}, (response) => { // 비동기 함수에서 reject()를 호출할 때 실행
console.log('FAIL');
});
then()은 또 다른 promise 객체를 반환한다. 따라서 아래와 같이 코드를 작성할 수 있다.
testPromise.then((response) => {
console.log('SUCCESS');
return response.data;
}.then((response) => {
console.log(JSON.stringify(reponse);
})
then()은 항상 Promise를 반환하기 때문에, 일반 객체를 return하는 경우 이를 Promise로 감싸서 반환한다.
여러 개의 Promise를 사용하기 위한 메서드를 제공한다.
// 모든 Promise가 이행된 후 실행
Promise.all([promise1, promise2]).then( ... );
// 한 개의 Promise가 이행되면 바로 실행
Promise.any([promise1, promise2]).then( ... );
// 첫 번째로 이행된 Promise를 인자로 실행
Promise.race([promise1, promise2]).then( ... );
Async 함수는 암시적으로 Promise 객체를 반환한다.
async function foo() {
return 1
}
// 위의 Async 함수와 동일하게 동작
function foo() {
return Promise.resolve(1)
}
await 키워드는 Async 함수 내에서 함수의 동작을 잠시 멈추고 다른 비동기 함수가 완료되기를 기다릴 때 사용한다.
function foo1(url) {
return requestData(url) // returns a promise
.catch(e => {
return fail(url) // returns a promise
})
.then(v => {
return success(v); // returns a promise
});
}
// 위의 promise chain과 동일하게 동작
async function foo2(url) {
let v;
try {
v = await fail(url);
} catch (e) {
v = await processError(url);
}
return success(v);
}
Javascript는 Single Thread를 사용하지만 Event Queue와 Web API를 이용해 비동기 작업을 수행할 수 있다. Web API를 이용해 setTimeout() 같은 비동기 작업을 수행하고, 완료한 작업은 Event Queue에 넣어놨다가 Call Stack이 비면 Event Queue의 작업을 Call Stack으로 넣어서 이어서 작동한다.
동작 원리를 고려했을 때, Javascript의 비동기 함수는 두 가지 특징을 갖는다.
const start = Date.now();
setTimeout(()=>console.log(`timeout ${(Date.now() - start)}`), 5);
// result: timeout 6
const start = Date.now();
setTimeout(()=>console.log(`timeout ${(Date.now() - start)}`), 5);
let i = 0;
while(i < 999999999) { i++; }
// result: timeout 593
setTimeout(()=>{
console.log(1);
let i = 0;
while(i < 999999999) { i++; }
console.log(2);
}, 5);
setTimeout(()=>{
console.log(3);
console.log(4);
}, 5);
잘 읽었습니다. 좋은 정보 감사드립니다.