javascript lodash 활용 꿀팁

Q&A 큐레이션

1. lodash 체이닝(_.chain)은 왜 사용하나요?

안녕하세요 로대쉬를 사용하다가 궁금한점이 있어서 질문 남깁니다. sortBy.map.filter 이런식으로 chain메서드 없이도 체이닝을 할 수 있는데 chain 메서드는 왜 사용하는지 어떤 장점이 있는지 문득 궁금해졌습니다. 혹시 이유를 아시는 분 있으시면 답변해주시면 큰 도움이 될 것 같습니다!


답변

사실 로데시 함수에서 chain 함수는 함수형 프로그래밍을 쉽게 구현하기 위해서 사용하는 함수이지만, 앞서 유근수님께서 답변주신것 처럼 지연평가가 필요해서 더 많이 사용되는것 같아요. (지연평가도 함수형 프로그래밍에 일부에요!) 일반적으로 JS에서 지원되는 map, filter 와 같은 람다식 함수들은 n 번의 시간 복잡도를 가집니다. 만약 map(...).filter(...) 식을 가진다면 2n 만큼의 복잡도를 갖게 되어요. 하지만 지연평가는 이터레이터 기법을 이용해서 여러 반복적인 작업을 n번의 순회에 모두 처리하는 기법을 사용합니다. (매 순회마다 처리해야할 로직들을 한번에 처리하며 다음 순회로 넘어가는 방법을 사용합니다) JS의 제너레이터 라는 문법을 이용하여 이터러블한 함수를 구현하고 이를 통해 지연평가를 합니다. 더 자세한건 여러 블로그를 참고하시면 될거에요 : ) "그러면 무적권! 지연평가를 활용하는것이 짱짱 좋은것인가?" 여기에 답변은 No 입니다 ㅎㅎ 그 이유는 지연평가가 여러 반복 로직이 복잡하게 엮여있는 경우에는 성능이 좋은것이 확실하나, 단순 반복에서는 map, filter 가 더 성능이 좋습니다. 이유는 단순히 map, filter는 언어 자체에서 지원하는 기능이기 때문에 반복 순회를 처리하는 과정이 더 효율적으로 짜여있기 때문이에요. 반면에 제너레이터를 이용한 구현시에는 .next()라는 메서드 실행을 통해 다음 순회로 넘어가기 때문에 JS 로직적으로 순회가 처리되어요. (아무래도 명령어 처리 효율이 안좋은 JS보다는 더 로우 레벨 언어로 구현된 map, filter 가 더 빠르겠죠?) 그러면 언제 지연평가를 쓰면 좋을까요? * 대상에 걸어야 하는 반복 로직의 갯수가 많을때 지연평가 효율이 좋습니다. (map(...).filter(...).map(...)...) 때에 따라서는 이러한 로데시 함수 구현없이 reduce 라는 순수 JS 문법을 통해 지연평가로 구현해야할 로직을 대신할수도 있어요! 여러 블로그 및 사이트에서 순수 자바스크립트로 구현을 했을때와 로데시로 구현을 했을때의 성능비교한것을 정리해주고 있어서 해당 자료도 같이 살펴보는 것을 추천드립니다 : ) 🎉 함께 검색해보면 좋은 키워드 🎉 * lodash * 함수형 프로그래밍(FP) * js generator * iterator * 지연 평가 구현 * lodash vs ES6 * reduce

외 1개 답변 보러 가기

2. lodash vs underscore 중 현업에서 어떤 라이브러리 사용하시나요?

lodash vs underscore중 어떤것을 더 많이 사용하시나요?


답변

레거시 프로젝트가 아니면 대부분 lodash를 사용합니다. lodash를 underscore의 개선 버전이라고 생각하시면 편합니다. (underscore는 2009년에, lodash는 2012년에 만들어졌습니다.) underscore에 있는 함수들은 거의 대부분 lodash에서도 사용이 가능하고, 성능이나 확장성에서도 lodash가 더 낫습니다. underscore는 중첩 객체(nested object)를 다루지 못하는 반면, lodash는 중첩 객체를 탐색하거나 cloneDeep같이 불변성 관리에 도움을 주는 함수를 제공합니다. 다만, 번들 사이즈를 따져봤을 때 lodash는 24.5kB, underscore는 8.2kb로 lodash가 3배 정도 더 큰 용량을 가지고 있기 때문에 lodash를 사용하신다면 트리 쉐이킹 혹은 babel-plugin-transform-imports과 같은 플러그인을 이용해서 modularize imports 사용을 고려하시는게 좋습니다. modularize imports는 import 구문을 내가 사용한 함수만 호출하도록 transform을 해줍니다. 아래는 예시입니다. [전] import { merge } from 'lodash' [후] import merge from 'lodash/merge'

외 1개 답변 보러 가기

3. React에서 데이터 정렬 (ordering)하기

예시코드 첨부했습니다. 데이터를 원하는 key에 따라 정렬 하려고 합니다. 버튼을 누르면 원하는 값으로 데이터를 보려고 하는데 문제는 정렬을 잘 했는데 데이터가 변하지를 않습니다. sort 메서드를 잘못 사용했나 싶어. console.log(data) 로 디버깅 해보면 data는 변화하는데 화면은 변하질 않아요. 오류를 찾아주세요.


답변

data.sort(orderByName) 을 통해 정렬되어 나온 array는 사실 변화한 것이 아닙니다. 쉽게 설명하면 기존의 data에 있는 array라는 껍데기는 그대로 있고 안에 있는 요소가 변화한 것입니다. 그래서 state가 변하지 않았다고 판단하고 이는 re-render가 발생하지 않습니다. - sort와 관련된 문서 입니다. https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array 이를 해결하려면 새로운 배열로 만들어 주어야합니다. 가장 간단한 방법은 spread 연산자를 이용해서 setData([...data.sort(orderByName)]) 이렇게 사용하면 될 것 같습니다. 추가적으로 lodash나 다른 라이브러리들을 이용해서 정렬했을 때 결과값을 새로운 배열로 return 해주는 것을 사용해도 좋을 것 같습니다

이 질문 바로 가기

4. React 객체 기본값 처리 어떻게 하시나요?

React로 프로젝트를 하면서 객체에서 값을 꺼내서 사용해야 할 일이 자주 있는데요, 객체에 값이 없거나 키를 잘못 전달받았을 경우를 대비해 주로 기본값을 지정해주고 있습니다. 코드를 작성하다보니까 기본값을 다양한 방법으로 지정하고 있는데 방법마다 차이가 있는지? 궁금해져서 질문 드립니다. 제가 쓰는 방식들 코드로 간단하게 정리해서 첨부합니다. 각 방법이 선호되는 경우나 우려되는 점이 있는지, 혹시 다른 분들이 주로 쓰는 방법이 있는지 등 관련된 어떤 의견이라도 좋으니 다양하게 듣고싶습니다!


답변

default key로 정의한 값이 사실상 사용하지 않는, 코드상 오류를 방지하기 위함이라면 key를 enum으로 정의하고 받아서 dataMap의 key가 enum이 되는것도 방법인것 같습니다. 그러면 그 외의 값이 내려오지 않도록 좀 더 type-safe하게 관리될 수 있을것 같습니다. 또 한가지는 _와 같이 lodash의 get을 사용해 default value를 넣어주고 계신것 같은데, lodash get의 소스코드를 보고 구현방법을 파악해보는 방법도 있습니다. 저라면 lodash처럼 크기가 큰 라이브러리를 사용하지 않고 key로 조회 후 없다면 defaultValue로 넣어주는 ||(or) 을 쓸 것 같습니다. const data = dataMap[key] || defaultValue; 그리고 typescript를 쓴다면 위와 같은 에러가 발생하지 않도록 더 타이트하게 코드를 짤 수 있습니다.

이 질문 바로 가기

5. First Load JS shared by all(번들 사이즈)를 줄이는 방법

실무에서 사용중인 next.js를 빌드하면 페이지가 공통으로 사용하는 번들의 용량이 나오는데 용량이 커서 그런지 빨간색으로 볼드처리 되어있습니다. 현재는 페이지로드 시간이 느리진 않는데 점점 코드가 많아지면 문제가 생길 수 있어서 번들 사이즈를 줄이려고 합니다. 번들 사이즈를 확인하고, 사이즈를 줄일 수 있는 좋은 방법이 있을까요?


답변

안녕하세요:) 제가 적용했던 몇가지 방법을 알려드리자면 1. 번들 사이즈를 확인해서 잘 사용하지 않는 라이브러리 제거 또는 대체하기 next/bundle-analyzer라는 라이브러리를 사용하면 번들을 구성한 파일, 라이브러리의 세부 용량을 확인할 수 있습니다. 용량이 큰 라이브러리의 경우 사용하지 않으면 제거하고, 대체할 수 있다면 라이브러리를 사용하지 않고 직접 구현하여 용량을 줄일 수 있습니다. 저도 실무에서 pdf를 보여주는 뷰어 컴포넌트를 만들어야 했었는데 pdf를 보여주기 위해 사용하는 react-pdf의 용량이 너무 커서 iframe을 통해 직접 뷰어를 구현했던 경험이 있습니다. 큰 용량을 차지하지만 잘 사용하지 않는 라이브러리가 있다면 대체하는 것도 한가지 방법이 될 것 같아요. 2. import cost를 확인하여 라이브러리에서 필요한 코드만 가져오기 vscode를 사용중이시면 import cost라는 익스텐션을 통해 각 파일이 import하는 모듈의 사이즈를 확인할 수 있습니다. module의 사이즈가 크고 해당 모듈에서 사용하는 코드가 한정적이라면 직접 코드를 Import하는 습관을 들이면 평소에서 용량에 많은 리소스를 줄일 수 있습니다. 예를 들어 lodash를 사용할 경우 export default를 통해 lodash 모듈을 불러오면 71.5kb 이고 ex) import _ from 'lodash'; join 함수만 가져오면 720b입니다. ex) import join from 'lodash/join'; 요약하면 1. 현재 프로젝트의 번들을 구성하는 모듈의 사이즈를 확인 -> 불필요한 라이브러리는 삭제하고, 대체할 수 있으면 대체한다. 2. 평소에 번들 사이즈를 키우지 않는 코딩 습관을 기른다 -> import cost를 통한 비용 체크 더 좋은 방법을 알아내시면 답변으로 저에게도 공유해주세요~

이 질문 바로 가기

6. react에서 난수 생성할 때 무엇을 사용하나요?

react에서 난수생성을 하려고 하는데 많이 사용되는 라이브러리가 있나요? 추천부탁 드립니다!


답변

react도 javascript기반이기 때문에 javascirpt 로 난수생성을 할 수 있어요! https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math/random 단, 보안과 관련된 것에서는 사용하지 말라고 나와있네요! 그리고 lodash에 있는 random 메서드도 많이 사용하는 것 같아요! https://lodash.com/docs/4.17.15#random

이 질문 바로 가기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!