1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptでも型を意識して実装するといいことがある! 〜2024年上期自己研鑽を通して学んだこと〜

Last updated at Posted at 2024-09-25

はじめに

この記事は、2024年上期に自主制作から学んだことおよび自己研鑽として取り組んだことをまとめた記事です。

自主制作から学んだこと

自主制作以外については記事を執筆することで学んだことをアウトプットしていますが、自主制作で学んだことはアウトプットできていないのでこちらの記事でアウトプットします。

型の理解が深まった

一番の収穫は型の重要性を(ようやく)理解できたことです。

HTMLElementのインスタンスかどうかで型を絞ろう

今までnullチェックを兼ねた早期リターンは今まで以下のようにしていたのですが、

const element = document.querySelector("[data-sample]");
if(!element) return;

今回レビューいただいた方から以下のようにHTMLElementのインスタンスかどうかで判定した方が良い、と言うことを教えていただきました。

const element = document.querySelector("[data-sample]");
if(!(element instanceof HTMLElement)) return;

上記のようにHTMLElementでチェックすることで、elementが持っているメソッドをコードエディターが自動で判定して予測として提示してくれるようになります!!!

例えば、button要素を取得した場合は、以下のようにHTMLButtonElementのインスタンスかどうかを判定します。

const buttonElement = document.querySelector("[data-button-sample]");
if(!(buttonElement instanceof HTMLButtonElement)) return;

上記の記述をすることで、HTMLButtonElementのインスタンスメソッドであるdisabledが予測変換に出てくるのです!!!とっても便利!!!
image.png

HTMLElementのインスタンスメソッドかどうかの判定だとdisabledは予測変換に出てきません><
image.png

元々属性を取得する時はgetAttributeを利用することが多かったのですが、上記のように型を絞った上で予測変換を利用した方がタイポを防げる、というメリットもあります。

nullチェックの要否は機械的に判定しよう

自主制作で以下のようなコードを書いていました。
この時自分は、elementsdata-sample属性を持っている要素を配列風オブジェクトにしているので、forEachで取り出しているelementは必ずdata-sample属性を持っており、valueは何かしらの値か空文字が格納されるため、nullチェックは不要だと考えていました。

const dataSampleKey = 'data-sample';
const elements = document.querySelectorAll(`[${dataSampleKey}]`);
elements.forEach((element) => {
  const value = element.getAttribute(dataSampleKey);
  const target = document.getElementById(value);
  console.log(target);
})

しかし、「ここは必ずstringが入ってくるだろう」と判断できるのは人間だけとのことで、「実際何が入ってくるか」よりは「前後関係はさておきこの変数に格納される可能性がある型は機械的に考えるとstringもしくはnullになる」ので、nullチェックをした方が良い、と言う考え方を学びました。
実際、TypeScriptのエラー判定が出るような設定をしたところ「stringかnullが入ってくるよ」というエラー判定が出ます。
image.png

上記のサンプルコードでnullチェックを行う場合は該当行にNull 合体演算子 (??)を利用すると良い、ということも学びました!

const target = document.getElementById(value ?? "");

JavaScriptで生成した要素を追加するときはDocumentFragmentを使おう

選択した都道府県に応じて都道府県の選択肢を変更する実装を行いました。
image.png
image.png

当初、「大阪」「京都」のようなinput要素を直接DOMに追加する実装を行なっていたのですが、選択肢の回数分Documentを直接操作するのはパフォーマンス的に良くない、ということでDocumentFragmentの存在を教えていただきました。

こうすることで、以下のようにDocumentFragmentを追加するときにだけDocumentを操作するので、DOMへのアクセスを1回だけに減らすことができます。

  1. 「大阪」のインプット要素を作成
  2. DocumentFragmentに追加
  3. 上記を都道府県の個数分繰り返す
  4. DocumentFragmentをDocumentに追加

パフォーマンス観点で優れているのでdocumentに要素を追加する場合は積極的に使っていきたいと思います!

その他こまごました学び

ARIA ライブリージョンは基本politeを使おう

上記に記載の通り、ユーザの操作に応じて選択肢など表示が変わることから、aria-live属性を利用してユーザに通知が届くような実装をしていました。
このときaria-live="assertive"を設定していたのですが、ARIA ライブリージョン(MDN)にも以下のように記載がある通り、aria-live="assertive"は緊急性の高い通知にのみ使用すべきで、通常はaria-live="polite"を使った方が良い、ということを学びました。

通常、aria-live="polite" のみが使われます。(中略)スクリーンリーダーはユーザーがアイドル状態になったときに読み上げを行います。
aria-live="assertive" は、即時に伝えてユーザーの注意を引く必要のある、時間にシビアな通知にのみ使用します。一般的に assertive なライブリージョンへの変更は、スクリーンリーダーがその時に読み上げているものに割り込みます。

data属性の属性名と値を変数名にするときはkeyvalueがおすすめ

いつも変数名をどうしたらいいのか悩んでしまうのですが、data属性は「key」と「value」の関係になっているとのことで、それぞれ変数に格納したい場合は以下のようにするのもおすすめです。

const dataSampleKey = 'data-sample-key';
const dataSampleValue = document.querySelector(`[${dataSampleKey}]`).getAttribute(dataSampleKey);

まとめ

今回、JavaScriptの品質向上を目的に自主制作を行いました。
社内の経験豊富なメンバーにレビューいただいたこともあり、自分が考慮できていなかった点やワンランク上の実装の仕方を学ぶことができました。
型の重要性を理解したことで、TypeScriptを学ぶことへのハードルがかなり下がったと感じています。
また、案件対応時に困っているメンバーをフォローできるようになったり、コードレビューでより品質が高い書き方を提案できたりと、チーム全体の品質向上に寄与できたと思います。

以下は自主制作始め、当初取り組む予定だったものをそれぞれの取り組み状況を載せています。

期初の目標と取り組み状況

期初の目標

2023年の自己研鑽を踏まえ、この半期では以下に取り組むこととしました。
なお、優先順位を考慮しMUSTを太文字としています。

  • インターネット関連
    • HTTPとは
    • ドメインネームとは
    • ホスティングとは
    • DNSとは
  • HTML
    • アクセシビリティ (2023年下期から後ろ倒し)
    • パフォーマンス
  • CSS
    • コンテンツモデルについて
  • コードレビュー力向上 (2023年下期から継続)
  • Javascript
    • DOMとは
    • ECMA Scriptの仕様周り(2023年下期から継続)

2024年9月時点での取り組み状況

MUSTの項目について、インプットとアウトプットをそれぞれ以下の通り取り組んでいます。

MUSTを優先で取り組んだため、WANT項目については現時点で全く取り組めていません。

2024年下期に取り組みたいこと

細かいところはまだ全く考えられていませんが、下期にはTypeScriptにチャレンジしようかなと思っています。
また学んだことを社内外に共有できるようがんばります!

参考

過去の取り組みはこちらです。
https://qiita.com/msuzuna/items/39009934edd7cb35e3ec

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?