多くの開発者が苦労しているJavaScript開発の1つの側面は、オプションの値を処理することです。 null
、undefined
、または実行時に初期化されていない可能性のある値によって引き起こされるエラーを最小限に抑えるための最善の戦略は何ですか?
一部の言語には、そのような状況に対応するためのアフォーダンスが組み込まれています。一部の静的に型指定された言語では、null
とundefined
は不正な値であると言え、プログラミング言語でコンパイル時にTypeErrorをスローします。 、しかしそれらの言語でも、実行時にnull入力がプログラムに流れ込むのを防ぐことはできません。
この問題をより適切に処理するには、これらの値がどこから来るのかを理解する必要があります。最も一般的なソースのいくつかは次のとおりです。
- ユーザー入力
- データベース/ネットワークレコード
- 初期化されていない状態
- 可能性のある機能何も返さない
ユーザー入力を処理する場合、検証が最初で最善の防御線です。私はその仕事を支援するためにスキーマ検証ツールに頼ることがよくあります。たとえば、reactをチェックしてください。 -jsonschema-form。
入力からのレコードのハイドレイティング
ネットワーク、データベース、またはユーザー入力から受け取った入力をハイドレイティング関数を介して常に渡します。たとえば、次を使用します。
ユーザーレコードをハイドレイトする値:
const setUser = ({ name = "Anonymous", avatar = "anon.png" } = {}) => ({
type: setUser.type,
payload: {
name,
avatar
}
});
setUser.type = "userReducer/setUser";
場合によっては、現在の状態に応じて異なるものを表示する必要がありますデータの。すべてのデータが初期化される前にページを表示できる場合は、そのような状況に陥る可能性があります。たとえば、ユーザーにお金の残高を表示しているときに、データが読み込まれる前に誤って$ 0の残高を表示する可能性があります。私はこの動揺したユーザーを何度も見ました。現在の状態に基づいて異なる出力を生成するカスタムデータ型を作成できます。
上記のコードは、無効な状態を表示できないようにするステートマシンです。天びんを最初に作成すると、uninitialized
状態に設定されます。状態がuninitialized
のときに残高を表示しようとすると、代わりに常にプレースホルダー値( “--
“)が取得されます。
これを変更するには、.set
メソッドまたはsetBalance
ショートカットを呼び出して値を明示的に設定する必要があります。 createBalance
ファクトリの下で定義しました。
状態自体はカプセル化されており、外部の干渉から保護して、他の関数が取得して設定できないようにします。無効な状態になります。
注:これに数値ではなく文字列を使用している理由がわからない場合は、お金の種類を次のように表すためです。丸め誤差を回避し、任意の有意な小数精度を持つことができる暗号通貨トランザクションの値を正確に表すために、小数精度が高い大きな数値文字列。
ReduxまたはReduxアーキテクチャを再使用すると、Reduでステートマシンを宣言できますx-DSM。
nullおよび未定義の値の作成を回避する
独自の関数では、null
またはundefined
の値。 JavaScriptに組み込まれていることを行うには、いくつかの方法が思い浮かびます。以下を参照してください。
nullを回避する
JavaScriptでnull
値を明示的に作成することはありません。これは、2つの異なる値を持つことの意味を実際に見たことがないためです。基本的に「この値は存在しません」を意味するプリミティブ値。
2015年以降、JavaScriptは、問題の引数またはプロパティに値を指定しない場合に入力されるデフォルト値をサポートしています。これらのデフォルトは、null
値では機能しません。私の経験では、これは通常バグです。このトラップを回避するには、JavaScriptでnull
を使用しないでください。
初期化されていない値または空の値に特殊なケースが必要な場合は、ステートマシンの方が適しています。上記を参照してください。
新しいJavaScript機能
null
またはの値。この記事の執筆時点では、どちらもステージ3の提案ですが、「将来から読んでいる場合は、それらを使用できる可能性があります。
この記事の執筆時点では、オプションの連鎖はステージ3の提案です。これは次のように機能します。
const foo = {};
// console.log(foo.bar.baz); // throws error
console.log(foo.bar?.baz) // undefined
ヌル合体演算子
また、仕様に追加されるステージ3の提案「ヌル合体演算子」 」は基本的に「フォールバック値演算子」のわかりやすい言い方です。左側の値がundefined
またはnull
の場合、次のように評価されます。右側の値。これは次のように機能します。
Promisesを使用した非同期Either
関数が値を返さない場合は、Eitherでラップすることをお勧めします。関数型プログラミングでは、Eitherモナドは、成功パスまたは失敗パスの2つの異なるコードパスをアタッチできる特別な抽象データ型です。 JavaScriptには、Promiseと呼ばれる非同期のどちらかのモナド風のデータ型が組み込まれています。これを使用して、未定義の値の宣言型エラー分岐を行うことができます。
必要に応じて同期バージョンを作成できますが、私はそれほど必要としませんでした。それはあなたの練習問題として残しておきます。ファンクターとモナドの基礎がしっかりしていれば、プロセスは簡単になります。それが恐ろしいと思われる場合でも、心配する必要はありません。 promiseを使用するだけです。これらは組み込みであり、ほとんどの場合正常に機能します。
多分配列
配列は、map
メソッドを実装します。配列の各要素に適用される関数。配列が空の場合、関数は呼び出されません。言い換えると、JavaScriptの配列は、Haskellなどの言語のMaybesの役割を果たすことができます。
Maybeとは何ですか?
Maybeは、オプションの値をカプセル化する特別な抽象データ型です。 。データ型には次の2つの形式があります。
- Just —値を含む可能性があります
- Nothing —値を含まない可能性があります
アイデアの要点は次のとおりです。
これは、コンセプトを示すための単なる例です。 flatMap
やflat
などの他の操作を実装して(たとえば、Just(Just(value))
複数の多分戻る関数を作成する場合)。しかし、JavaScriptには、これらの機能の多くをすぐに実装できるデータ型がすでにあるので、通常は代わりに配列に到達します。
次のような関数を作成する場合結果が生成されない場合があります(特に複数の結果が存在する可能性がある場合)。配列を返すための優れたユースケースがある場合があります。
map
は、null
とundefined
の値を回避するのに非常に便利な空のリストでは呼び出されませんが、配列の場合は覚えておいてください。 null
とundefined
の値が含まれている場合、それらの値を使用して関数が呼び出されるため、実行している関数が
またはundefined
の場合、上記のように、返された配列からそれらを除外する必要があります。これにより、の長さが変更される可能性があります。コレクション。
Haskellには、maybe
という関数があります()は関数を値に適用します。ただし、値はオプションであり、Maybe
にカプセル化されます。 JavaScriptのArray
データ型を使用して、基本的に同じことを行うことができます。
maybe
はフォールバック値を取ります、次に多分配列、次に多分配列(1つの値を含むか、何も含まない配列)にマップする関数であり、関数を配列の内容に適用した結果、または配列が次の場合はフォールバック値を返します。空。
便宜上、toMaybeArray
関数も定義し、maybe
関数をカレーして作成しました。このデモンストレーションで最も明白です。
本番コードでこのようなことをしたい場合は、ユニットテスト済みのオープンソースライブラリを作成して簡単にしました。それはメイベアレイと呼ばれています。他のJavaScriptMaybeライブラリに対するMaybearrayの利点は、ネイティブJavaScript配列を使用して値を表すことです。そのため、それらに特別な処理を加えたり、前後に変換するために特別なことをしたりする必要はありません。デバッグ中に多分配列に遭遇したとき、「この奇妙なタイプは何ですか?」と尋ねる必要はありません。これは単なる値の配列または空の配列であり、これまでに100万回見たことがあるでしょう。
次のステップ
EricElliottJS.comには、たくさんのコンテンツを含む、もっとたくさんのコンテンツがあります。ビデオ、演習、記録されたスクリーンキャスト、および簡単なヒントの一覧です。メンバーでない場合は、今が足りないものを確認する絶好の機会です!