(내용 정리에 생각을 덧붙일 경우 🤔
이모지를 첨부합니다.)
How To Create An On-Off Button For Your Mind - 마음 속 켜기/끄기 스위치 만들기 (미디엄 유료)
매일 저널을 작성한다.
매일 명상하라.
일정 시간에 전자기기를 멀리 해보라.
공부 방법
디테일 높이기
추가 팁
How to Improve Software Architecture Skills Daily | by Ella sheer | Jun, 2021 | Level Up Coding - 날마다 소프트웨어 설계 스킬을 향상시키는 방법
마주치는 문제마다 두 개 이상의 해결책을 찾아보자.
상충하는 부분의 목록을 만들고 그 중에서 해결책을 골라라.
다양한 사람과 기술적인 논의를 해 보라.
정규화 규칙
NFD
각
-> ㄱ + ㅏ + ㄱ
NFC
각
-> 각
NFKC, NFKD
단위
자모 단위
문자 단위
정렬
소프트웨어 (SW) 개발 경험이 먼저다 :: Channy’s Blog
잘 정리된 이력서보다 중요한 것 – by minieetea
지원동기가 명확한가?
지원동기를 통해 지원하는 회사에 얼마나 관심 있는지 판단할 수 있다.
지원동기를 보고 퇴사를 언제 할 수 있을지 판단할 수 있다.
지원동기를 통해 ‘동기’ 를 어떻게 만들어낼지 판단할 수 있다.
어떻게 일하는가?
퍼포먼스를 내는가?
어려움을 겪었는가?
본인을 잘 이해하는가
JS Is Weird - JS의 독특한 부분을 퀴즈로 엮은 것
true + false
: 답은 1이다. true
는 number 타입일 때 1이고 false
는 0이기 때문이다.[,,,].length
: 답은 3이다. 마지막 콤마는 트레일링 콤마이다.[1, 2, 3] + [4, 5, 6]
: 답은 “1,2,34,5,6” 이다. 배열은 더하기로 연결할 때 해당되는 내용의 문자열로 변환된다.0.2 + 0.1 === 0.3
: 답은 false이다. 꽤 유명한 문제인데 floating point의 고질적인 문제라고 해야하나.10,2
: 답은 2이다. 콤마로 이어진 표현식은 마지막 값을 리턴한다.!!""
: 답은 false이다. 빈 문자열은 Falsy값이고, 이를 불린값으로 변환하는 !!
를 썼다.+!![]
: 답은 1이다. 빈 배열은 Truthy이라서 불린값인 true
로 변환되었고 거기에 더하기 기호를 사용하여 숫자 타입으로 변환되었다.!!!true
: 답은 false이다.true == "true"
: 답은 false이다. 두 값은 숫자 타입으로 변환되는데 "true"
는 NaN
으로 변환된다.010 - 03
: 답은 5이다. 010
은 8진수로 다루어진다."" - - ""
: 답은 0이다. 빈 문자열은 0으로 치환되었고, 0 - -0
라는 표현식이 된 것이다.null + 0
: 답은 0이다. null
은 숫자 0으로 변환된다.0/0
: 답은 NaN이다. 다른 언어라면 ZeroDivisionError
같은게 나야겠지만 JS는 그런 류의 에러는 취급 안한다.1/0 > Math.pow(10, 1000)
: 답은 false다. 두 값은 모두 Infinity
로 처리된다.true++
: 답은 SyntaxError이다. 놀랍게도 true
값을 변수에 담아두고 그 변수에다 ++
연산을 하면 정상적으로(?) 2가 된다."" - 1
: 답은 -1이다. 빼기 연산은 문자열처럼 취급되지 않고 숫자끼리의 연산에만 사용하는 것으로 간주한다. 빈 문자열은 0으로 간주된다.(null - 0) + "0"
: 답은 “00”이다. null
은 0으로 간주된다. 그리고 바로 위의 문제에서 언급한 것처럼 문자열과 다른 타입끼리 연산할 경우 문자열 연산으로 간주된다.true + ("true" - 0)
: 답은 NaN이다. "true"
를 숫자형으로 변환하면 NaN
이 나온다. 이 시점에서 연산의 결과는 결정된 것이다.!5 + !5
: 답은 0이다. 0 이상의 숫자는 Truthy 값이다. 이를 불린 값으로 뒤집었으니 0이다.[] + []
: 답은 ""이다. 3번 문제대로 배열을 문자열 변환하면 내용물 그대로 나온다. 하나 유의할 점은 [,]
도 문자열로 변환하면 빈 문자열이다. 마지막 콤마가 트레일링 콤마 처리되었기 때문이다.NaN === NaN
: 답은 false이다. IEEE-754 위원회에서 처음 이렇게 결정되었다고 한다. 다만 Object.is
로 비교하면 true
값이 나온다.NaN++
: 답은 NaN이다.undefined + false
: 답은 NaN이다. undefined
는 숫자로 형변환되지 않고 NaN
이 나온다.+0 === -0
: 답은 true이다. Object.is
로 비교하면 true
값이 나온다.- "" + + "1" * null - [,]
: 답은 0이다. 표현식을 치환하자면 -0 + 1 * 0 - 0
이 된다.export default thing
is different to export { thing as default }
- JakeArchibald.com - default export, named + default 의 차이
import { thing } from './module.js'
형식으로 파일을 가져올 때 thing
은 레퍼런스를 가져오는 것이기 때문에 원래 파일에서 재할당 등의 변경을 일으키면 가져오는 쪽에서도 변경이 일어난다.let { thing } = await import('./module.js');
형식의 import는 일반적인 객체 분해처럼 가져온 값을 새로운 식별자에 할당한다.하지만 export default
는 몇 가지 다르고 특이한 동작이 있다.
export default
는 값을 직접 전달한다. 이는 export default
가 선언문이 아니라 표현식으로 동작하기 때문이다. 그래서 export default thing
을 하면 thing
이 export 되기 전에 어딘가 숨겨진 변수에 할당되는 것처럼 동작한다.export { thing as default }
는 레퍼런스를 전달한다.export default function
도 해당 함수의 레퍼런스를 전달한다. 만약 export default
에 함수가 전달되는 것도 표현식처럼 동작하게 된다면 가져다 쓰는 쪽에서는 아직 할당되지 않은 함수라서 undefined
를 맛보게 될 것이다.// These give you a live reference to the exported thing(s):
import { thing } from './module.js';
import { thing as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
// This assigns the current value of the export to a new identifier:
let { thing } = await import('./module.js');
// These export a live reference:
export { thing };
export { thing as otherName };
export { thing as default };
export default function thing() {}
// These export the current value:
export default thing;
export default 'hello!';
foo
라는 함수를 먼저 선언한 뒤에 export default foo
를 하고서 순환 참조를 하게 되면 아직 foo
의 할당이 일어나기 전이기 때문에 문제를 겪게 될 것이다. 하지만 export default function foo ...
는 위에서 언급한 특수 케이스에 포함되어 바로 레퍼런스가 연결되기 때문에 문제없이 참조할 수 있다.JavaScript iterators and generators: A complete guide - JS 이터레이터와 제네레이터 가이드
someObj[Symbol.iterator] = function () {...}
형식으로 구현하는 것이다.next
함수가 있는 객체이며 이 함수의 리턴 값은 done
, value
속성으로 이루어진 객체다.next
함수를 가진 객체를 리턴하기 전에 클로저를 활용하여 루프에 따라 점점 증가하는 변수를 다룬다던가 하는 방식으로 구현하는 방법 등이 설명되어있다.next
를 호출하며 다음 단계로 넘어갈 때의 내부 로직을 다루는 것이 어려울 수 있다.제네레이터는 이터레이터를 만드는데 사용한다. 굉장히 추상적이지만 그게 전부다. 특정한 경우에 제네레이터는 아주 유용하게 활용될 수 있는데, 원하는대로 정지했다가 다시 재개할 수 있는 제네레이터의 특성을 적극적으로 활용하는 것이다.
Functional-ish JavaScript. Functional programming is a great… | by Daniel Brain | Medium - 함수형’스러운’ 자바스크립트
순수한 함수를 작성하지 못하더라도 예측 가능하게 작성하라.
상태를 보수적으로 다루자.
상태를 다루기로 했다면, 스코프를 활용하라.
const
, let
이 다루어지는 범위 안에서만 활용한다.상태를 캡슐화하라.
memoize
함수를 만들어 추상화할 수 있다.예외를 다루는데 너무 걱정하지 말라.
콜백 대신 Promise, Async/Await을 사용하라.
resolved
, rejected
, pending
같은 상태가 있긴 하지만 적절한 수준 안에서 캡슐화되어있다고 볼 수 있다.목적에 맞다면 클래스를 사용하라.
타입을 사용하라.
가능하면 불변 객체를 만들자.
함수형스러운 테스트를 작성하라.
실용적으로 접근하라.
Simple CSS Hack to Reduce Page Load Time | by Mayank Gupta | Jun, 2021 | JavaScript in Plain English - 페이지 로딩 시간을 줄이는 간단한 CSS 핵
CSS는 페이지 로딩 시간에 영향을 미치는 주요한 요소 중 하나다.
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">
onload
속성에서 보다시피 페이지가 로딩되자마자 미디어 속성을 다시 “all” 로 바꾼다. 하지만 이러한 방법은 최초 로딩에 영향을 미치지 않는 스타일에만 적용해야 한다.preact-portal/preact-portal.js at master · developit/preact-portal · GitHub - Preact용 Portal API 구현하기
Preact로 Portal을 이용하려면 preact/compat
을 사용해야 한다. 번들 사이즈를 줄이기 위해 가능하면 compat
을 쓰지 않으려다보니 비슷한 걸 구현해야 하는데, 이미 몇년 전에 만들어져있는 preact-portal
패키지를 참고하여 간단한 형태로 한번 만들어보았다.
render
함수를 호출해야 하기 때문에 원본 코드에서는 setTimeout
을 사용하여 업데이트 시에 블락이 일어나지 않도록 만들고 있다. 그런데 기억하기로는 이펙트의 실행이 requestAnimationFrame
을 활용하고 있으니까 상관 없어 보인다.function Portal({ children, into }) {
const renderRef = useRef(null);
useEffect(() => {
const container =
typeof into === "string" ? document.querySelector(into) : into;
if (!renderRef.current && container && hasChildren(children)) {
renderRef.current = render(children, container);
}
return () => {
renderRef.current = null;
};
}, [into, children]);
return null;
}
GitHub - nektos/act: Run your GitHub Actions locally 🚀
make
대신 로컬 태스크 러너도 활용할 수 있게 된다. Makefile
대신 .github/workflows
를 활용하게 되는 것이다..github/workflows
폴더를 읽어들여 도커 API를 사용하여 필요한 이미지를 생성하고 액션에 맞는 컨테이너를 실행한다. 그래서 도커 의존성이 있다.