Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

JavaScript

逆FizzBuzzを解いてみた2

全然書いた記憶はなかったんですが、昔の僕は逆FizzBuzz という問題に挑戦してました。 逆FizzBuzzを解いてみた - Panda Noir この解答コードがもうちょいシンプルに書けたので載せておきます おさらい: 逆FizzBuzzとは? [1,2,3,4,5,…] のように並んだ数列が…

pubsub パターンの現時点でのベストプラクティス

以前pubsub パターンのベタープラクティスを考えたんですが、よく考えたらイベント名を設定する必要なかったです。 これでよさそう↓ class PubSub<Payload extends unknown[]> { private listeners: ((...payload: Payload) => void)[] = []; subscribe(callback: (...payload: Payload)</payload>…

ワンライナーでバージョン文字列を比較する

結論: localeCompare を使う a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'}) 参考: https://stackoverflow.com/a/65687141 localeCompare は IE11 でも使えるので、使えない心配はほぼありません。 しかし、locale とついているため…

循環参照がある配列で flat を呼び出すとどんどん長くなる

何に使えるかは全然わからないですが発見したのでメモ。 まず循環参照を持った配列を定義します。 const a = []; a[0] = a; a[1] = 0; これの flat を呼ぶと面白いことが起きます。 console.log(a.flat()); // [ <ref *1> [ [Circular *1], 0 ], 0, 0 ] console.log(</ref>…

オプショナルチェーン演算子は短絡評価される

{}.a?.(console.log('hoge')) ↑この時 console.log('hoge') は評価されない。つまりログに hoge と出力されない {a:()=>{}}.a?.(console.log('hoge')) ↑この時は console.log('hoge') も評価される。ログに当然 hoge と表示される。 || 演算子や && 演算子は…

関数はアロー関数と function どちらで書くべきなのか?

結論: (トップレベルで関数を宣言するときに限り)function かアロー関数かは好みの問題。 アロー関数が出てきた当初と状況が変わってきた www.pandanoir.info 2016年に「function よりアロー関数を使うべき(function は適切な場面でのみ使うべき)」という記…

LSP のファイル名変更機能を使った mv コマンドを実装した

タイトルのとおりです。 作ったもの tsserver には、ファイルを移動させると相対パスを自動で修正する機能があります。 例えば A.tsx を B.tsx にリネームすると、A.tsx を import していた箇所が自動で修正されます。 import {Component} from './component…

@testing-library/react の debug が途中で途切れてしまう問題について

debug の出力には文字数制限があります。それを回避する方法について紹介します。 in short: debug ではなく prettyDOM(baseElement)) を使う const { debug } = render(<HelloWorld />); debug(); ↓ import { prettyDOM } from '@testing-library/react'; const { baseEle</helloworld>…

data-attributes に色々渡してみる

const Component = () => <div data-foo={xxx} /> みたいに色々な値を data-attribute に渡してみました。 結果: undefined, null: そもそも追加されない NaN: ワーニングが出る そのほか: 文字列に変換されて値としてセットされる 検証に使ったデモがこちら</div>

JSON.stringify の返り値は undefined になることがあるよ

JSON.stringify(undefined) は undefined です。 以上です。 JSON.stringify(undefined) の結果は?— panda noir (@le_panda_noir) 2022年1月20日 正答率10%。みんな undefined を渡したときの挙動を知らなかったっぽいですね(僕も知りませんでした) 補足 JS…

Jest モック方法まとめ

追記: 本記事は誤っています 本記事は誤っています。 実際の jest ランタイムの解説として不適切な箇所があります。jest ランタイム難しい… 時間があるときに直そうと思ってるんですが時間が取れません… とりあえず本記事を参考にしないでください。 本文 毎…

YouTube のスワイプで消せるフロートカードを実装する

最近のYouTube君がよく使うこのUIパターン、名前ついてるのか気になってる(フロート型で下スワイプで消せて上部にバーがついてるやつ) pic.twitter.com/EJeLQ8wSoS— クロパンダ (@le_panda_noir) 2022年8月12日 ↑これを CSS + JS で作りました。フロートカー…

Prettier は結局何をやっているのか?コードの動作は変わってしまわないのか?

結論: AST を作って、それを元にコードをフォーマットしているから、プログラムの動作は一切変わらない 結論をもう書いたので、意味が分かった人はここより下は不要。ちょっとだけ用語とかの解説をする。 そもそも AST とは? AST とは Abstract Syntax Tree …

touchcancel イベントをハンドリングしないと iPad で大変なことになるぞ

結論: iPad は4本指で上にスワイプするとホーム画面に戻る便利機能があります。これをブラウザで行うと touchstart → touchmove → touchcancel の順で発火します。 touchend が永遠に発火しません。 結論で言いたいことは完結してるので、以下はその補足説明…

zx を使っていい感じに SIGINT を捌く

シェルスクリプトで ctrl + C を押して中断したときのクリーンアップ処理を書くのはそこそこ大変です(頑張ればできますが)。今回は zx を使った、クリーンアップ処理を含むコードの書き方を紹介します。 そもそも zx とは? alt シェルスクリプト的なものです…

pubsub パターンに対する思いと現時点でのベタープラクティス

なんらかの payload を渡したいとき、インターフェイスを定められない。これに尽きる。静的型付けとも相性が悪い。 payload と言ってるのは要するに window.addEventListener(eventName, event => {}) の event のことだ。TypeScript はかなり頑張って型付け…

in-place merge sort を実装してみた

こちらの論文を参考に書きました。 http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=D04E90C1CB92030C1B92452FB9E192A0?doi=10.1.1.22.8523&rep=rep1&type=pdf 実装 さくっと実装をまずお見せします。 const mergeSort = (arr: number[], L = 0, …

lookahead lookbehind(先読み、後読み)まとめ

lookahead (?=pattern) negative lookahead (?!pattern) lookbehind (?<=pattern) negative lookbehind (?) (?<=Promise<)void(?=>) 1年に100回くらい「先読みとあと読みってどっちがどっちだ?どっちがどういう記法だっけ?」って悩むのでほんといい加減にし…

軽量な summary/details を作りたい

detailsを閉じているときに DOM を消しておきたいので作りました(作成時間5分) const Details: VFC<{ summary: ReactNode; detail: () => ReactNode }> = ({ summary, detail, }) => { const [showsDetail, setShowsDetail] = useState(false); return ( <details open={showsDetail} onToggle={() => se</details>…

document.readyState と load, DOMContentLoaded のタイミングについて

結論 complete になると同時に load が発火する(仕様) interactive になったあとかつ complete になる前に DOMContentLoaded が発火する(仕様) 厳密には complete になったあとに load が発火するという仕様です。この前後関係があるため、 readystatechange…

Timers Promises API が最高

名前から既にワクワクするこのAPIは、なんとPromiseを返すsetTimeout、setInterval関数を提供しています!最高です… というわけで今回はそれの紹介です。 基本的な使い方 await setTimeout(1000) ←これができるんです!素晴らしくないですか?? top-level a…

Vite所感

ここ最近 Vite で軽くアプリ作ってたので感想。 Vite とは? 4行で書くと webアプリ開発に特化したビルドツール バンドラではない(バンドル"も"できる) 超高速 dev server & HMR もちろんプロダクションビルドもできる こんな感じ。ビルドツールなので、webp…

eslint-plugin-import を使ってディレクトリ単位でアクセス制限を敷く

TypeScript を使っていて、「この関数、他のディレクトリからはアクセスして欲しくないんだけどテストのために export しなきゃ行けないな…」みたいなケースありませんか?実は、ESLint でうまく設定してやると解決できます!今回はその方法を紹介します。 お…

デフォルト引数を悪用して変数宣言を減らす

const state = reactive({ count: 42, flag: true, str: 'hello world', computed: computed(() => { const {count, flag, str} = state; return flag ? count : str; }), }); このような Vue3 のコードがあったとします。このとき、わざわざconst文を使わず…

npm publishの練習をするならverdaccio + docker

みなさん、npm publish、怖くないですか??? npmでライブラリ公開したときに踏みつけた地雷7つ - Panda Noir npmでアップデートするときに踏みがちな3つの落とし穴 - Panda Noir 僕はもうトラウマだらけです。怖いです。しかし、いつかは克服しなければい…

esbuild なら React の playground が5秒で出来る!!!!!

esbuild はプラグインなしで JSX・TSXをコンパイルできるから、React のプレイグラウンドがすぐ作れる!! $ npm init --yes $ npm i esbuild react react-dom $ esbuild src/main.tsx --bundle '--define:process.env.NODE_ENV="development"' --outfile=ou…

Record & Tuple Proposal がすごい話

github.com このプロポーザルの話です(2020年8月現在Stage2) どういうプロポーザルか? Record と Tuple は、簡単にいうとプリミティブ的なオブジェクトと配列です。どういうことかというと、次のようなことができるようになります。 [1, 2, 3] !== [1, 2, 3…

.eslintrcを別フォルダに移す

ルートディレクトリにコンフィグファイルがちらばっていると気になりませんか?僕はとても気になります。そこで、設定ファイルを別ディレクトリへ移す方法をご紹介します。 package.jsonに追記するだけで良い たとえば.config/eslintrc.jsへ移動させたとしま…

Vue3に書き直してみる

Vue2からVue3へ書き直す際に情報が不足していて困ったのでまとめておきます。 公式ドキュメント まだversion3の公式ドキュメントは揃っていません。マージされたPRかRFCを見るしかない状況です。 migrate from v2 to v3 ※「これだけ押さえれば7割くらいは移…

{}は簡易Symbolにできる

Symbolの使い方として、たとえば独自の特殊値を持ちたいと言うものがあります。 // myFind: 配列と関数を受け取り、 // 関数を満たす要素が見つかればその要素、 // 見つからなければnullを返す const myFind = (arr, f) => { for (let i = 0; i < arr.lengt…