Original Posts
https://javascript.plainenglish.io/say-goodbye-to-these-5-bad-javascript-practices-b4f51599b4ee
https://javascript.plainenglish.io/say-goodbye-to-7-bad-javascript-practices-1de41ca57f0a
아래 코드는 웹 페이지에서 쿠키를 모두 지우는 코드입니다.
document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`))
우리가 작성하는 코드는 컴퓨터를 위해 작성하는 것이지만, 함께 일하는 동료도 내가 작성한 코드를 읽는다는 것을 잊지 말아야 합니다.
디버깅 목적으로 개발자들은 종종 에러 메세지를 콘솔에 찍습니다.
try {
fetch(url, {
method: 'post',
...
})
} catch (err) {
// When the request goes wrong, we don't have any perception
console.log(err)
}
물론 개발자가 에러를 잡기 위해 사용하는 경우로는 괜찮은 방법입니다. 그러나 서비스를 사용하는 유저 입장을 배려하여 한 단계 더 나아가야할 필요가 있습니다.
try {
fetch(url, {
method: 'post',
...
})
} catch (err) {
Toast(err.message)
}
매직 넘버는 개발자만 아는 하드 코딩된 리터럴입니다. 매직 넘버를 사용한다면, 코드를 읽는 사람에게 코드의 목적이 무엇인지 전달하는 과정에서 혼선을 줍니다.
// index1.js
if (status === 1 || status === 2) {
// ...
} else if (status === 3) {
// ...
}
// index2.js
if (status === 1 || status === 2) {
// ...
}
위 코드에서 status 변수의 1,2,3이 어떤 의미를 갖는지 파악하기 어렵습니다.
따라서 아래와 같이 constant 선언을 통해 이 변수에 어떤 의미를 담고 있는지 명확하게 할 필요가 있습니다. constant 선언 때에 주석을 달아주는 것도 의미 전달에 큰 도움이 됩니다.
const STATUS = {
// It is an adult and has real-name authentication
adultRealName: 1,
// It is a minor and has real-name authentication
minorRealName: 2,
// Not real-name authentication
notRealName: 3,
// ...
}
// index1.js
if ([ STATUS.adultRealName, STATUS.minorRealName ].includes(status)) {
// ...
} else if (status === STATUS.notRealName) {
// ...
}
// index2.js
if ([ STATUS.adultRealName, STATUS.minorRealName ].includes(status)) {
// ...
}
fetch('/a')
.then((a) => {
fetch('/b', { a })
.then((b) => {
fetch('/c', { b })
.then((c) => {
console.log(c)
})
})
})
await
키워드를 사용하면 위 코드를 간결하게 만들 수 있습니다.
const a = await fetch('/a')
const b = await fetch('/b', { a })
const c = await fetch('/c', { b })
console.log(c)
하나의 함수에 너무 많은 파라미터는 코드를 이해하기 어렵게 만들고 또 함수를 호출하는 과정에서 버그가 날 확률을 높입니다.
const getUser = (name, weight, mobile, gender, address, hobby, ...) => {
// ...
return ...
}
getUser('fatfish', 100, 183, ....)
필연적으로 함수 호출에 많은 파라미터를 넘겨야 한다면, 객체를 생성하여 조금 더 깔끔한 코드를 작성할 수 있습니다 (구조 분해 할당을 통해 객체로부터 필요한 변수들을 가져옵니다).
const getUser = (options) => {
const { name, weight, mobile, gender, address, hobby, ... } = options
// ...
return ...
}
getUser({
name: 'fatfish',
weight: 100,
mobile: 183
...
})
String을 Number형으로 형변환 할 때 + sign을 이용하면 직관적으로 보입니다.
const str = '123456'
const num = +str
console.log(num) // 123456
그러나 Number
혹은 parseInt
함수를 사용하면 조금 더 의미론적이고 명확하게 표현할 수 있습니다. 왜냐하면, 코드 작성자가 형변환이라는 명확한 목적으로 갖고 코드를 작성했다는 것을 보여주기 때문입니다.
const str = '123456'
const num1 = Number(str)
const num3 = parseInt(str)
console.log({ num1, num2 }) // { "num1": 123456, "num2": 123456 }