본 글은 유튜브를 보다가 우연히 찾은 Javascript Pro Tips - Code This, NOT That 영상인데, 자바스크립트 ES6에서 지향하는 클린 코드를 잘 정리해주셔서 리마인드할 겸 다시 정리한다.

console.log, console.table

1
2
3
const foo = { name: "tom", age: 30, nervous: false };
const bar = { name: "dick", age: 40, nervous: false };
const baz = { name: "harry", age: 50, nervous: true };

위의 3가지 객체들을 콘솔에 나타낼 때 console.log(foo); console.log(bar) ...처럼 작성하면 쓸데없는 코드가 늘어나게 되고, 한 눈에 봐도 비효율적으로 보인다.

1
console.log({ foo, bar, baz });

이렇게 한번에 나타낼 수 있다. {} 표현은 정말 많이 쓰인다.

1
console.table([foo, bar, baz]);

console.table에 배열 객체로 넘겨주면 정리된 표 형식으로 볼 수도 있다.

console.time

1
2
3
4
5
6
console.time("looper");
let i = 0;
while (i < 1000000) {
i++;
}
console.timeEnd("looper");

console.time부터 console.timeEnd까지의 시간을 측정하여 출력해준다. 함수의 인자로 들어가는 이름이 일치해야 그룹으로 묶인다.

console.trace

1
const deleteMe = () => console.trace("bye bye database");

console.trace를 사용하면 함수가 호출될 때의 stack trace를 확인할 수 있다.

destructuring

1
2
3
4
5
6
7
8
const turtle = {
name: "Bob",
legs: 4,
shell: true,
type: "amphibious",
meal: 10,
diet: "berries",
};

이 turtle 객체를 함수의 인자로 넘겨서 객체 안의 값에 접근해보자. feed라는 함수를 예로 들면,

잘못된 코드

1
2
3
function feed(animal) {
return `Feed ${animal.name} ${animal.meal} kilos of ${animal.diet}`;
}

이는 명백히 비효율적이고 잘못된 코드이다. 클린 코딩의 방법은 2가지인데,

올바른 코드

1
2
3
function feed({ name, meal, diet }) {
return `Feed ${name} ${meal} kilos of ${diet}`;
}

위처럼 인자 자체를 객체를 풀어주는 방법이 있고,

올바른 코드

1
2
3
4
function feed(animal) {
const { name, meal, diet } = animal;
return `Feed ${name} ${meal} kilos of ${diet}`;
}

위처럼 함수 내에서 별도로 객체를 풀어주는 방법이 있다.

Template Literals

1
2
3
4
5
6
const horse = {
name: "Topher",
size: "large",
skills: ["jousting", "racing"],
age: 7,
};

위 객체의 값을 활용해서 새로운 값을 선언해보자.

잘못된 코드

1
2
3
4
5
6
let bio =
horse.name +
" is a " +
horse.size +
" horse skilled in " +
horse.skills.join(" & ");

backticks을 이용하면 위처럼 +를 사용하여 하나하나 붙여줄 필요가 없다.

올바른 코드

1
2
const { name, size, skills } = horse;
let bio = `${name} is a ${size} skilled in ${skills.join(" & ")}`;

위에서 언급한 destructuring으로 horse 객체를 풀어주고 backticks를 사용하면 정말 간단하고 가독성도 좋게 변수를 선언할 수 있다.

Spread Syntax

1
2
const pikachu = { name: "Pikachu" };
const stats = { hp: 40, attack: 60, defense: 45 };

위의 두 객체를 하나로 합치고 싶다면 어떻게 해야할까.

잘못된 코드

1
2
3
pikachu["hp"] = stats.hp;
pikachu["attack"] = stats.attack;
pikachu["defense"] = stats.defense;

위처럼 하나하나 할당하거나, push를 사용해서 하나하나 넣어준다면 stat 객체에 100가지 요소가 들어있다면 말도 안되는 코드가 되어버릴 것이다.

올바른 코드

1
const lvl0 = { ...pikachu, ...stats };

Spread 방식을 사용하면 위처럼 간단하게 합친 새로운 객체를 만들어낼 수 있다.

loops

1
const orders = [500, 30, 99, 15, 133];

orders 배열을 loop 방식으로 계산해야 할때

잘못된 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const total = 0;
const withTax = [];
const highValue = [];
for (i = 0; i < orders.length; i++) {
//reduce
total += orders[i];

//map
withTax.push(orders[i] * 1.1);

//filter
if (orders[i] > 100) {
highValue.push(orders[i]);
}
}

전통적인 for loop 방식으로 코드를 작성하는 방법도 있지만, 자바스크립트에서는 기본적으로 reduce, map, filter 메소드를 지원한다.

올바른 코드

1
2
3
const total = orders.reduce((acc, cur) => acc + cur);
const withTax = orders.map((v) => v * 1.1);
const highValue = orders.filter((v) => v > 100);

async / await

1
2
3
const random = () => {
return Promise.resolve(Math.random());
};

랜덤 숫자를 콜백 형식으로 지정된 순서로 생성하여 더하는 함수를 만들 때

잘못된 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const sumRandomAsyncNums = () => {
let first;
let second;
let third;

return random()
.then((v) => {
first = v;
return random();
})
.then((v) => {
second = v;
return random();
})
.then((v) => {
third = v;
return first + second + third;
});
};

.then을 체인처럼 엮어서 작성하는 경우가 많다.

올바른 코드

1
2
3
4
5
6
const sumRandomAsyncNums = async () => {
const first = await random();
const second = await random();
const third = await random();
return first + second + third;
};

asyncawait을 적절히 활용하면 순서를 보장하는 코드를 간단하게 작성할 수 있다.

마치며

ES6 문법으로 정말 혁신적으로 코드의 길이를 줄이고 효율적인 코드를 작성하는 방법이 많다. 영상에 있는 내용도 일부에 불과하다. 나도 push를 사용해서 값을 집어넣거나 .then을 칭칭 엮어서 코드를 짠 기억이 있다. 지금부터라도 ES6 문법에 맞게 클린 코딩을 지향해야겠다.

ES6 문법에 관한 총 정리를 해놓은 고마운 분이 계시니 차근차근 읽어보면 좋을 것 같다.