Intro
요 근래 싸피에서의 프로젝트를 마무리하는 기간이 겹치며, 포스팅에 집중할 시간이 도저히 나지 않았다.
매일 집에서 역삼을 왕복하는 시간에도 틈틈히 공부를 하려 노력하고 있는데, 이 때의 공부들은 더욱이 휘발성이 심한 것 같다.
이번 포스팅에서는 이동 중에 보았던 유용한 자바스크립트 문법들을 정리하고, 내가 알고 있던 것과, 몰랐던 것에 대해 정리해보곘다.
1. 익숙한 문법
1.1 간결한 boolean 반환
const isPositive = (number) => { return number > 0; };
true / false를 if 조건문으로 나누어서 코드 작성할 필요 없이 return 문으로 boolean 값을 간결하게 반환할 수 있다.
1.2 삼항 연산자로 조건문 축약
const checkAge = (age) => { age >= 18 ? "어른" : age >= 13 : "청소년" : "아이"; }
복잡한 if, else if의 구분 없이 삼항 연산자의 중첩을 통해서 간결하게 작성할 수 있다.
하지만 이러한 방식이 항상 가독성이 좋은 것은 아니다.
삼항 연산자가 길어지거나, 중첩이 깊어지면 조건문이 더 가독성이 좋다.
적재적소에 활용하는 것이 중요하다.
1.3 프로퍼티 축약 표현
const myname = 'sio'; const myage = 29; const me = { myname, myage }; // {myname: 'sio', myage: 29}
객체의 프로퍼티 값으로 변수를 사용하는 경우, 프로퍼티 이름을 생략할 수 있다.
이때 프로퍼티 이름은 변수의 이름으로 자동 생성된다.
1.4 화살표 함수 사용
// const add = function(a, b) { // return a+b; // }; const add = (a, b) => a + b;
화살표 함수를 사용하면 function 키워드와 return 문을 생략하고도 함수 작성을 간결하게 할 수 있다.
1.5 구조 분해 할당
// const person = { name: "sio", age: 30}; // const name = person.name; // const age = person.age; const { name, age } = person;
객체의 프로퍼티를 추출하는 반복적인 코드를 간소화할 수 있다.
1.6 default 값 할당
// const createMenu = (options) => { // options = options || {}; // const size = options.size || 'large'; // const color = options.color || 'blue'; // return { size, color }; // } const createMenu = ({size='large', color='blue'} = {}) { return { size, color } ; }
기본 값을 설정해줌으로 써 코드를 더욱 간결하게 만들 수 있다.
나는 React Props의 default 값을 작성할 때 자주 사용했다.
1.7 Promise로 동기처리
// function delayAndDoSomething(callback) { // setTimeout(() => { // callback(); // }, 1000); // } // delayAndDoSomething(() => console.log('1 second passed')); const print = () => console.log('1 second passed'); new Promise((resolve) => setTimeout(resolve, 1000)).then(print);
콜백 함수 대신 Promise를 사용하여 비동기 작업을 보다 직관적으로 처리할 수 있다.
2. 내가 몰랐던 문법
2.1 이중부정을 통한 boolean 값 반환
// const result = data ? true : false; const result = !!data;
이중 부정 연산자를 통해 데이터가 truthy한지 빠르게 확인할 수 있다.
삼항 연산자보다 짧고 명확한 코드 작성이 가능하다.
부정 연산자의 사용법이 헷갈려서, 정확한 사용법을 알아보았다.
!
- 논리 부정 연산자
- 피연산자의 truthy/falsy 여부와 반대로 T/F로 반환
- truthy라면 1(false), falsy라면 0(true)
!!
- 논리 이중부정 연산자
- 정확한 논리결과를 T/F로 반환하기 위해 사용
- undefined, null, 0에 대해서 false 반환
- [주의] 문자열 “0”은 true
- 나머지는 모두 true
!!!
- 논리 삼중부정 연산자
- !!의 부정
2.2 메서드 축약 표현
const person = { name: 'Sio', sayHi() { console.log('Hi!' + this.name); }, };
메서드 선언시 function 키워드를 생략해도 가능하다.
2.3 스프레드 연산자
const arr1 = [1, 2, 3]; // const arr2 = arr1.concat([4, 5]); // 배열 결합 const arr2 = [...arr1, 4, 5]; const obj1 = { a: 1, b: 2 }; // const obj2 = Object.assign({}, obj1, {c: 3}); // 객체 병합 const obj2 = { ...obj1, c: 3 };
이 경우는 스프레드 연산자를 사용하는 방법은 알고 있었지만, 반대로 불편한 방법을 몰랐던 경우이다.
2.4 옵셔널 체이닝과 Nullish 병합 연산자
let user = null; // let userName = user !== null && user !== undefined ? user.name : "Guest"; let userName = user?.name ?? 'Guest';
2.5 함수 호출에서의 옵셔널 체이닝
// if (obj && typeof obj.method === 'function') { // obj.method(); // } obj?.method?.();
옵셔널 체이닝 (?.):
- 객체가 undefined나 null일 때 에러 없이 안전하게 접근할 수 있게 해준다.
- user?.name은 user가 null이나 undefined면 undefined를 반환하고, 그렇지 않으면 user.name을 반환한다.
Nullish 병합 연산자 (??):
- 왼쪽 피연산자가 null이나 undefined일 때만 오른쪽 피연산자를 반환한다.
- 여기서는 userName이 undefined일 때 'Guest'를 반환한다.
2.6 Object.fromEntries()
const entries = [ ['name', 'sio'], ['age', 100], ]; const obj = {}; entries.forEach(([key, value]) => { obj[key] = value; }); const obj2 = Object.fromEntries(entries);
Object.fromEntries()는 키-값 쌍의 목록을 객체로 변환한다.
2.7 reduce를 활용한 반복 처리
const numbers = [10, 20, 30, 40, 50]; // let sum = 0; // for(let i = 0; i < numbers.length; i++) { // sum += numbers[i]; // } const sum = numbers.reduce((prev, next) => [prev + next, 0]);
reduce는 알고 있던 개념이었지만, 내 기준엔 직관적이지 못한 것 같아서 자주 안쓰게 되는 것 같다.
reduce:
- 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다.
- prev는 누적값, next는 현재 처리 중인 요소.
- 두 번째 인자 0은 초기값으로, 생략 가능하다.
2.8 콤마 연산자
let x = 10; // x++; // x = x + 5; x = (x++, x + 5);
콤마 연산자의 동작 원리:
- 콤마로 구분된 표현식들을 왼쪽에서 오른쪽으로 평가한다.
- 마지막 표현식의 결과를 반환한다.
- 여기서는 x++가 실행된 후 x + 5가 평가되어 그 결과가 x에 할당된다.
2.9 파이프라인 연산자 (제안 단계)
const addOne = x => x + 1; const double = x => x * 2; // const result = double(addOne(5)); // 12 const result = 5 |> addOne \> double;
파이프라인 연산자 |>:
- 아직 제안 단계에 있는 기능으로, 현재 JavaScript에서 사용할 수 없다
- 함수 호출을 더 읽기 쉽고 체이닝하기 쉽게 만드는 것이 목적
- 왼쪽의 값을 오른쪽 함수의 인자로 전달한다
3. 마무리
코드를 간결하게 작성하는 것도 중요하지만, 가장 중요한 것은 가독성을 고려하는 것이다.
짧은 코드는 효율적이지만, 너무 축약된 코드는 오히려 가독성을 떨어트리고 협업의 효율성을 저하시킨다.
몇 번의 프로젝트를 경험하며 느낀 점은, 반복적인 코드가 더 나을 때도 많다는 것이다.
때로는 반복적인 조건문이 더 직관적일 수 있으며, 가독성을 우선시한 코드는 유지보수와 디버깅이 훨씬 용이하다.
복잡한 로직을 간단히 줄이려는 시도는 코드의 의도를 모호하게 만들 수 있으므로, 상황에 맞는 적절한 균형이 필요하다.
결국, 효율성과 가독성의 균형을 유지하는 것이, 결국 개발자의 역량과 코드의 품질을 좌우한다고 생각한다.
서비스를 사용하는 고객만이 우리의 유일한 사용자가 아니다.
코드를 함께 읽고 유지보수하는 동료 개발자들도 중요한 사용자다.
나와 함께하는 개발자들을 위해 배려할 수 있는 개발자가 되고 싶다.