本文へジャンプ

JavaScript「Null判定」を忘れずに

Posted by MONSTER DIVE

JavaScript「Null判定」を忘れずに

はじめに

ブログを担当するMDマークアップエンジニアのAYUです。
今回は「Null判定」について書きました。

個人制作、練習用のスクリプトであれば「Null判定」を甘めに妥協して...設定してもいいかもしれません。しかし、実際の業務・規模の大きい開発などの場合はこれが無い原因で思わぬエラーに引っかかってしまうかもしれません。

Null & Undefined

本記事の前に Null と Undefined について説明します。

Undefined

下記の場合に Undefined が返されます。

  • 変数を宣言したが値がない
  • 未定義のプロパティを参照した
  • 関数の値が返されなかった

Null

Null は意図的に空の場合に用います。
以上から「Undefined」は 定義されていない・参照することを想定してない、といった非意図的な意味合いを持ちます。それに比べて Null は意図的に「それは空である」ことを示す違いがあります。

Null処理をしていないソース

下記ソースコードは、Null処理をしていません。
ボタンを押すと、ランダムにテキストが生成されるソースコードです。
※ソースは TypeScript で書いてます。

class ClickAction {
 // type
 buttonEl: HTMLButtonElement
 targetAreaEl: HTMLDivElement
 // constructor
 constructor(){
 this.buttonEl = document.querySelector('.buttonEl')!as HTMLButtonElement
 this.targetAreaEl = document.querySelector('.target_area')!as HTMLDivElement
 this.configure()
 }
 // push action
 private buttonAction() {
   const buttonEl = this.buttonEl
   const targetEl = this.targetAreaEl
   const texts = ['当たり', 'ハズレ', 'まあまあ'];

   buttonEl.addEventListener('click', () => {
     const random = Math.floor( Math.random() * texts.length)
     targetEl.insertAdjacentHTML('afterbegin', texts[random])
   })
 }

 private configure() {
   this.buttonAction()
 }
}

const clickAction = new ClickAction()

このソースのままだと、クリックしたタイミングでテキストは永遠に生成されてしまいます。
また、 "生成されるエレメント" がもしも無かったような場合にエラーになってしまう恐れがあります。
これは、私が意図していません。

これを解決するためには、少なくとも下記の対応をしたほうが安全です。
次の章でその解決方法を記述します。

  • ボタンエレメントがもしも無かった場合
  • 生成される要素エリアに子要素があるのか

解決方法 - hasChildNodes・querySelector

「hasChildNodes」と「querySelector」を用いることで今回はハンドリング処理を行います。

hasChildNodes

エレメントの子要素の有無を判定が真偽値で判定出来ます。(詳細はこちら)

querySelector

セレクター式で合致した要素を取得できます。
もしも、要素が取得出来ない場合はNullが返ってきます。(詳細はこちら)
それらを用いて、先ほどのソースコードに "searchButtonメソッド・resetActionメソッド"の 判定を追加しました。

class ClickAction {
 // type
 buttonEl: HTMLButtonElement
 targetAreaEl: HTMLDivElement
 // constructor
 constructor(){
 this.buttonEl = document.querySelector('.buttonEl')!as HTMLButtonElement
 this.targetAreaEl = document.querySelector('.target_area')!as HTMLDivElement
 this.configure()
 }

 // searchButton
 private searchButton() { // 追加
   const buttonEl = this.buttonEl
   if(buttonEl !== null) {
     console.log('ボタンはあります')
   } else {
     alert('要素がないです')
   }
 }

 // reset action
 private resetAction() { // 追加
   const targetEl = this.targetAreaEl
   const childTarget = targetEl.firstChild
   if (targetEl.hasChildNodes()) {
     console.log('子要素が見つかりました')
     targetEl.removeChild(childTarget)
   } else {
     console.log('子要素が見つかりませんでした')
   }
 }

 // push action
 private buttonAction() {
   const buttonEl = this.buttonEl
   const targetEl = this.targetAreaEl
   const texts = ['当たり', 'ハズレ', 'まあまあ'];

   buttonEl.addEventListener('click', () => {
     this.resetAction()
     const random = Math.floor( Math.random() * texts.length)
     targetEl.insertAdjacentHTML('afterbegin', texts[random])
   })
 }

 private configure() {
   this.buttonAction()
   this.searchButton()
 }
}

const clickAction = new ClickAction()

これにより、上記で述べましたが以下の内容を防ぐことが出来ました。
他にも合理的な方法があると思うので、改めて知識を吸収する必要があります。

  • ボタンエレメントがもしも無かった場合
  • 生成される要素エリアに子要素があるのか

最後に

以上が『JavaScript「Null判定」を忘れずに』でした。
今回は「searchButtonメソッド・resetActionメソッド」の追加を例に「hasChildNodes・querySelector」の例を用いました。
ここまで読んでいただき、ありがとうございます。

Recent Entries
MD EVENT REPORT
What's Hot?