저번 포스팅에 이어서 Javascirpt를 멋지게, 그리고 프로답게 쓰는 법에 대해서 알아보도록 하겠습니다. 이번 포스팅도 대부분 가독성에 중점을 두었습니다.
1. Nullish Coalescing Operator ( ?? ) - Null 병합 연산자
// ❌ bad 💥
function printName(text) {
let message = text;
if (text === null || text === undefined) {
message = "No Message";
}
console.log(message);
}
전달받은 텍스트가 null 이거나 undefined인 경우에 No Message를, 텍스트가 있는 경우라면 message를 출력하는 함수입니다.
위처럼 작성하게 되면 간단한 역할을 하는 함수에도 불구하고 코드가 매우 길어집니다.
// ⭕️ better 🌈
function printMessage(text) {
const message = text ?? 'No Message';
console.log(message);
}
이럴 경우에 Nullish Coalescing Operator인 ?? 를 사용하게 되면 보다 직관적이고 깔끔하게 작성할 수 있습니다. null 이거나 undefined인 경우에만 ?? 오른쪽 코드가 실행됩니다.
1-1. Default Parameter 와의 차이점
// vs DefaultParameter
function printMessage(text = 'No Message') {
console.log(text);
}
// text가 undefined인 경우에만 No Message 출력
여기서 Default Paramter를 사용하면 똑같이 구현할 수 있다는 생각이 들 수 있습니다. Default Paramter는 undefined인 경우에만 해당되고 null 인 경우는 해당되지 않습니다.
1-2. Logical Operator ( || ) 와의 차이점
// vs LogicalOperator
function printMessage(text) {
const message = text || 'No Message';
console.log(message);
}
// null, undefined 이외에 false면 전부 No Message
Logical Operator 는 false에 해당하는(Nan, '', null, undefined 등)값이 오게되면 || 오른쪽의 코드가 실행되는 차이점을 가지고 있습니다.
2. Object Destructuring - 구조 분해 할당
// ❌ bad 💥
const blog = {
name: 'leffept',
link: 'leffept.tistory.com',
};
fucntion displayBlog(blog) {
displayName(blog.name);
displayLink(blog.link);
}
위 코드의 경우에는 blog. 코드가 반복되어 사용되고 있습니다. 반복되는 횟수가 늘어나면 상당히 지저분한 코드가 됩니다.
// ⭕️ better 🌈
function displayBlog(blog){
const { name, link } = blog;
displayName(name);
displayLink(link);
}
Object Destructuring을 활용할 경우 위의 코드처럼 보기 좋게 작성할 수 있습니다. blog object 안의 name, link 값을 변수로서 구조 분해 할당 해주는 방식입니다.
3. Spread Syntax ( ... ) - 전개 구문
// ❌ bad 💥
const blog = { name: 'leffe', link: 'leffept.tistory.com' };
const post = { title: 'javascirpt', view: 777 };
const newObj = {
name: blog.name,
link: blog.link,
title: post.title,
view: post.view,
};
두개의 objcet가 있을 때 합해서 새로운 object를 만들어야 하는 경우에 Spread Syntax를 활용하여 간단하게 할 수 있습니다.
// ⭕️ better 🌈
const newObj = { ...blog, ...post };
const newObj2 = { ...blog, ...post, title: 'pretty Javascript' }; // title update
수동적으로 값을 할당해 줄 필요없이 보기 좋게 변경되었습니다. 또한 뒤에 key, value를 적어주면 해당 key에 대한 value를 update할 수도 있습니다. 이 외에도 Array와 같은 다양한 곳에서 사용됩니다.
4. Optional Chaining ( ? )
// ❌ bad 💥
const blog = {
name: 'leffe',
link: 'leffept.tistory.com',
post: {
title: 'Javascript'
},
};
const blog2 = {
name: 'leffe2',
link: 'blog2.tistory.com',
};
function displayBlogPost(blog) {
if (blog.post && blog.post.title) {
console.log(blog.post.title);
}
}
하나는 새로 개설한 blog라 post가 존재하지 않고, 다른 blog는 존재한다고 하였을 때 blog의 title을 보여주는 코드입니다. 마찬가지로 코드가 길어진다면 지저분해 보일 가능성이 높습니다.
// ⭕️ better 🌈
function displayBlogPost(blog) {
if (blog.post?.title) {
console.log(blog.post.title);
}
}
? 라는 Optional Chaining을 사용하면 post 라는 object가 있는 지를 체크한 후 있다면 title을, 없다면 바로 false를 반환합니다.
// ⭕️ better 🌈
function displayBlogPost(blog) {
const title = blog.post?.title ?? 'No Post Yet;
console.log(title);
}
또한, 앞서 소개한 Nullish Coalescing Operator을 사용하여 더 보기좋게 만들 수 있습니다.
5. Template Literals - 템플릿 리터럴
// ❌ bad 💥
const blog = { name: 'leffe', link: 'leffept.tistory.com' };
console.log('Hello, This is ' + blog.name + ', link is : ' + blog.link);
문자열을 이어서 출력할 때 일반적으로 + 연산자를 사용하여 할 수 있습니다. 하지만, 작성하기에 불편합니다.
// ⭕️ better 🌈
const blog = { name: 'leffe', link: 'leffept.tistory.com' };
const { name, link } = blog;
console.log(`Hello, This is ${blog.name}, link is : ${blog.link}`);
Template Literals를 사용하면 더 간편하게 작성할 수 있습니다.
6. Array Operator (filter, map, reduce 등) & chaining
// ❌ bad 💥
function getEvenNumber(items) {
return items.filter((num) => num & 2 === 0);
}
function mutiplyBySeven(items) {
return items.map((num) => num * 7);
}
function sumArray(items){
return items.reduce((a, b) => a + b, 0);
}
const evens = getEvenNumber(items);
const multiple = multiplyBySeven(items);
const sum = sumArray(multiple);
console.log(sum);
배열과 관련된 연산을 하는 경우에 Array Opterator를 활용하면 좋습니다. 하지만, 사용하는 빈도에 비해 함수가 너무 많아 보이고, 할당 해주는 부분이 불필요해 보입니다.
// ⭕️ better 🌈
const result = items
.filter((num) => num & 2 === 0)
.map((num) => num * 7)
.reduce((a, b) => a + b, 0);
console.log(result);
위와 같이 연속성을 갖는 경우에 Array Operator을 chaining 해줌으로써 꽤나 보기 좋게 만들 수 있습니다.
7. Async / Await
// ❌ bad 💥
function displayBlogName() {
fetchBlog()
.then((blog) => {
fetchDetail(blog)
.then((name) => {
updateUI(blog, name);
});
});
}
Promise를 중첩하여 사용하는 경우에 코드는 매우 길어지고 가독성 또한 떨어지게 됩니다.
// ⭕️ better 🌈
async function displayBlogName() {
const blog = await fetchBlog();
const name = await fetchDetail(blog);
updateUI(blog, name);
}
두 가지 이상의 Promise를 연결해서 사용할 경우에는 async / await 을 사용하면 좋은 코드를 만들 수 있습니다. 이전 코드에 비해 한눈에 이해하기 쉬워진 것을 확인할 수 있습니다.
최근에 Javascirpt를 공부하면서 도움이 될만한 내용들을 정리해보았습니다. 위에 적힌 예시가 무조건 좋은 것만은 아니지만, 대부분의 상황에서는 좋을 것이라고 생각됩니다. 읽기 좋은 코드가 잘 만든 코드라는 말이 이러한 곳에서 나오는 것 같습니다.
읽어주셔서 감사합니다.
'SW개발 > Javascript' 카테고리의 다른 글
[Javascript]if, else 문 최소화하기 (5) | 2021.08.17 |
---|---|
[Vue]Computed 와 Watch 언제 사용할까? (feat. computed vs methods) (0) | 2021.05.09 |
[Vue]v-if vs v-show (0) | 2021.05.08 |
[Vue]라이프 사이클 알아보기 (0) | 2021.04.03 |