![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTHQQP%2Fbtq65SVZiA5%2FKKjDnAfuUF0cU3crMhckrk%2Fimg.png)
https://styled-system.com https://rebassjs.org https://theme-ui.com 라이브러리 코드를 참고해보장!
우테코3기 프론트엔드 리뷰어님들의 계약이 이제 만료되었다. 그냥 보내기에는 아쉬워서 마지막 인사를 해드리고 싶었고, 그게 이벤트 기획까지 가게 되었다. 계획은 리뷰어님들이 계시는 슬랙 코드리뷰 채널에서, 크루가 직접 미션 봇과 똑같이 위장을 해서 인사말이 가득한 노션링크를 뿌리는 것이었다. 그런데 사정이 생겨서 못하게 생겼고, 다른 방법이 없을까 고민하던 도중에, 그냥 미션 봇과 똑같이 생긴 슬랙봇을 만들어버리자 생각했다. 한번도 만들어 본적없었고, 그날 즉석해서 만들어진 계획이었기 때문에 완성할 수 있을지도 미지수 였다. 그래도 재밌을것같아서 시도해보았다. 검색한지 얼마되지 않아서 바로 아래 링크의 글을 찾았다. https://blog.gangnamunni.com/post/typescript-slack..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvaiz2%2Fbtq60IlIkOS%2FcyESkMFaQy4h4QagIlrXJ1%2Fimg.png)
CRA CRA는 create react app의 약자로써, React를 시작할 수 있는 초기 환경을 모두 셋팅해준다. npx create-react-app my-app 명령어로 실행할 수 있다. * CRA에는 기본적으로 모든 패키지들이 dependencies에 들어가있다. 이유는? CRA를 사용해서 그 위에 코드를 작성했을 뿐인데, 리뷰로 "이 라이브러리는 왜 dev에 없는가"에 대한 리뷰를 많이 받은것 같다. 그만큼 package.json이 가지는 의미가 중요하다는 거겠지. 그런데 우리는 CRA를 썼을뿐, package.json에 있는 코드를 한치의 의심도 없이 사용했다. 그 만큼 신뢰성있는 라이브러리니까! 그리고 이 설계는 Dan Abramov가 의도적으로 설계한 것이다. https://github...
명확한 프로그래밍의 핵심은 이름짓기다. 변수는 프로그래머가 하려는 일에 관해 많은 것을 설명해준다. 단, 이름을 잘 지었을 때만 그렇다. 사실 나는 이름을 잘못 지을 때가 많다. 고민을 충분히 하지 않아서거나, 개발을 더 하다 보니 문제에 대한 이해도가 높아져서거나, 혹은 사용자의 요구가 달라져서 프로그램의 목적이 변해서 그럴 때도 있다. 특히 이름의 중요성은 그 사용 범위에 영향을 많이 받는다. 한 줄 짜리 람다식에서 사용하는 변수는 대체로 쉽게 파악할 수 있다. 맥락으로부터 변수의 목적을 명확히 알 수 있어서 한 글자로된 이름을 짓기도 한다. 마찬가지로, 간단한 함수의 매개변수 이름도 짧게 지어도 될 때가 많다. 물론 자바스크립트와 같은 동적 타입언어라면 나는 이름 앞에 타입을 드러내는 문자를 붙이는..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSR40t%2Fbtq6KPsjvjR%2FNhvbMdy00PprCMKKis2SX1%2Fimg.png)
오우. 코드를 보고 바로 yes를 해버린 나를 반성한다. greatest의 초기값이 0이므로, arr가 0이상의 원소로 이루어져 있을 때만 유효하다. arr가 [-1,-2,-3,-4,-5]라면 -1가 답이어야 하는데 0이 나올것이기 때문이다. 객체를 인자로 복사없이 넣었으므로, 참조값으로 컨트롤하게 되므로 기존 객체에 변경사항이 반영된다. a1,a2는 같은 참조값을 가지고, b1,b2는 원시값이기 때문에 각각 분리해서 생각하고, c1,c2도 같은 참조값을 가진다. 아.. 값만 생각하고 바로 1번을 찍어버린 나를 반성한다. map은 배열을 반환하는데 ㅠㅅㅠ 함수선언문은 호이스팅이 된다. 즉, immaBeOnTop()은 first가 나온다. foo()도 호이스팅된 2개의 함수선언문 중 마지막 것이 반영되고 ..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flbj2H%2Fbtq6PDYbs7e%2FtbkkbfQq4dFl61BiT1FLck%2Fimg.png)
set이 중복된 원소를 제거하므로 arr는 [3,1,2,4]가 되고, (순서는 변하지 않는다.) arr의 길이는 4, arr의 인덱스2의 요소는 2가 된다. 익명함수가 즉시 실행되고 있으므로 IIFE가 맞다. HOF는 고차함수를 의미한다. 고차함수는 함수를 인자로 전달받거나, 함수를 결과로 반환하는 함수를 말하는데, fn를 인자로 받고 있으므로 고차함수에 해당한다. array를 Object 형태로 바꾸는 효율적인 방법을 고르는 문제이다. a는 spread 연산자를 매 iteration마다 하기 때문에 b가 효율적이다. 인자로 Function이 들어오면 그 function을 실행시키고, 아니면 a그대로를 return하는 함수이다. () => "Batman"은 함수이므로 실행된 결과값인 "Batman"이 반..
리팩터링은 결국 프로그램의 요소를 조작하는 일이다. 함수는 데이터보다 다루기가 수월하다. 함수를 사용한다는 건 대체로 호출한다는 뜻이고, 함수의 이름을 바꾸거나 다른 모듈로 옮기기는 어렵지 않다. 여차하면 기존 함수를 그대로 둔 채 전달 함수로 활용할 수도 있기 때문이다. 이런 전달 함수를 오래남겨둘 일은 별로 없지만 리팩터링 작업을 간소화하는데 큰 역할을 한다. 반대로 데이터는 함수보다 다루기가 까다로운데, 그 이유는 이런식으로 처리할 수 없기 때문이다. 데이터는 참조하는 모든 부분을 한 번에 바꿔야 코드가 제대로 동작한다. 짧은 함수 안의 임시 변수처럼 유효범위가 아주 좁은 데이터는 어려울 게 없지만, 유효범위가 넓어질수록 다루기 어려워진다. 전역 데이터가 골칫거리인 이유도 바로 여기에 있다. 그래서..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcuheqc%2Fbtq6AP0Nshq%2FfBKgAjNQMx6FMLqECWlmW0%2Fimg.png)
.sort() 메서드는 inplace로 동작하기 때문에, 변환된 값이 원래 배열에 그대로 반영된다. 그러므로, 1번, 2번 구문은 true이다. 그런데 3번 구문은 좌항, 우항이 값은 같으나 서로 다른 메모리를 참조하고 있을 것이므로 false이다. set은 중복된 값을 제거시킨다. 근데 mySet구문에서 {a:1}와 {a:1}는 다른 주소값을 가지고 있다. 그러므로 set과정에서 원소가 사라지지 않는다. 그것을 다시 array로 spread해주었으므로 답은 1번이다. Object.freeze는 기본적으로 객체의 수정을 막는 역할을 한다. 하지만 depth가 깊은 프로퍼티에 대해서는 적용되지 않는다. user.age를 수정하려 한다면 에러가 나겠지만 user.pet.name은 depth가 2이상이므로 f..