JavaScript データ型チェックチートシート - DEV コミュニティ
JavaScript (JS) は軽量で、インタープリタ型またはジャストインタイムコンパイル型のプログラミング言語です。ファーストクラス関数としての機能があります。
この投稿では、一般的な JavaScript データ型チェック、落とし穴、特有の解決策を詳細に解説します。
クラシック JavaScript データ型チェック
以下は、JavaScript での最も一般的なデータ型チェックのコレクションです。変数が Date や Promise、ただの旧式の JavaScript オブジェクトや配列を含んでいるかをチェックしたい場合は、ここに全てあります。
プリミティブ型から number、boolean、string の検出、関数の検出まで全て。
JavaScript の変数がオブジェクトを含んでいるかをチェックする
typeof
はオブジェクトに対して 'object'
を出力します。
これは null
と配列に対しても同様です。
const object = {};
console.log(typeof object); // 'object'
console.log(typeof null); // 'object'
console.log(typeof []); // 'object'
console.log(object instanceof Object); // true
console.log(null instanceof Object); // false
console.log([] instanceof Object); // true
さらに、配列の場合と同じように、フレーム間の通信があり、オブジェクトと配列を共有する傾向があるため(JavaScript 配列型チェック - 「is array」対オブジェクト深掘り を参照)、単純なオブジェクトとクラスのインスタンスを区別するのは難しいです。
JavaScript では全てがオブジェクトなので、存在しないプロパティにアクセスしようとすると静かに失敗します(つまり undefined
を返します):
console.log('aaaaa'.noProperty); // undefined
console.log([].nothing); // undefined
慣用的な JavaScript コードでは、例えば growl
メソッドを持つオブジェクトが期待されますが、他のものが渡されるかもしれません:
function safeGrowl(anything) {
if (anything.growl) {
anything.growl()
}
}
safeGrowl('hello'); // 何もしない
safeGrowl({ growl() { console.log('Growl!') }}); // Growl!
教訓は、何かがオブジェクトであるかどうかをチェックしないことです。必要なプロパティがあるかどうかをチェックしてください(これを「ダックタイピング」と呼びます)。
値が JavaScript の文字列かどうかをチェックする
文字列については typeof
チェックを使用できます。
オブジェクトチェックと同じように、JavaScript は文字列ではないものを文字列として使おうとするときに、大声で失敗することはず、通常はそれを強制的に変換したり、.toString
を呼び出したりします。
const string = 'Hello World';
console.log(typeof string); // 'string'
// テンプレートを使用した文字列への暗黙の強制変換
const helloCount = 2;
const newString = `Hello number ${helloCount} at ${new Date('2019-06-23T21:00:26.861Z')}`;
console.log(newString);
// 'Hello number 2 at Sun Jun 23 2019 22:00:26 GMT+0100 (British Summer Time)'
これは日付や数字にも機能します。直接 toString メソッドを実装していない配列や他のオブジェクトの場合は、JSON.stringify を使用することをお勧めします。
const myArray = ['a', 'b', 'c'];
const mySimpleObject = { key: 'value' };
console.log(`${myArray} ${mySimpleObject}`); // 'a,b,c [object Object]'
console.log(`${JSON.stringify(myArray)} ${JSON.stringify(mySimpleObject)}`)
// '["a","b","c"] {"key":"value"}'
値が JavaScript の Number/Integer (数字/整数) かどうかをチェックする
JavaScript の Number は楽しさの宝庫です。object
チェックと同様に、NaN
(Non a Number)値というゴッチャがあります。NaN
は、オペランドの一つが Number でない場合に算術を試みた結果です。
NaN
の奇妙な点は自分自身と等しくないことと、実際には Infinity
や - Infinity
と同じように Number であることです。
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(typeof NaN); // 'number'
console.log(typeof Infinity); // 'number'
console.log(typeof -Infinity); // 'number'
console.log(typeof 123); // 'number'
NaN
でないことをチェックする
Number が NaN
の一つのチェック方法は次のとおりです:
const a = NaN;
function isNotANumber(maybeNotANumber) {
return maybeNotANumber === maybeNotANumber;
}
isNotANumber(a); // true
お勧めのアプローチは、組み込みの Number.isNaN
関数を使用することです:
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('abc')); // false
console.log(Number.isNaN(1234)); // false
console.log(Number.isNaN(123.11)); // false
console.log(Number.isNaN(true)); // false
Number.isNaN
とグローバル isNaN
の違いは、Number.isNaN
は渡された値が Number で_かつ_ NaN
であることをチェックします。
古いグローバル isNaN
関数は、単に何かが数字ではないことを文字通りにチェックします。
console.log(isNaN(NaN)); // true
console.log(isNaN('abc')); // true
console.log(isNaN(1234)); // false
console.log(isNaN(123.11)); // false
console.log(isNaN(true)); // false
JavaScript の変数が整数を含んでいるかをチェックする
JavaScript の変数(または値)が整数であるかをチェックするには Number.isInteger
を使用できます:
console.log(Number.isInteger(123)); // true
console.log(Number.isInteger(12.3)); // false
console.log(Number.isInteger(123.0)); // true
JavaScript の変数が使える Number 値を含んでいるかをチェックする
使える入力値を持っているかをチェックするには、その型が number
であり、値が NaN でないことを確認します:
function isValidNumber(maybeNumber) {
return typeof maybeNumber === 'number' && !Number.isNaN(maybeNumber);
}
console.log(isValidNumber('aaaaa')); // false
console.log(isValidNumber(NaN)); // false
console.log(isValidNumber(123)); // true
console.log(isValidNumber(1.23)); // true
値が boolean であるかどうかをチェックする
JavaScript の文字列や数値型のように、JavaScript では何かが boolean であると仮定する(または boolean にキャストする)パターンがあります。それは JavaScript のゆるい型付けのため、論理演算子を boolean 以外の値と共に使用できるからです。これは通常、「真偽性」と「偽性」の概念を通じて説明されます。
JavaScript が boolean を求められ、下記の値のいずれかが与えられた場合、常に「偽」に評価されます。
問題の値(偽とされる値)は次のとおりです:false
、0
、''
(またはその他の空文字列)、null
、undefined
。他の値は全て真と評価されます。
undefined
の場合とは異なる何かが false
を意味する場合には、typeof
を使用することによって、値が偽である_かつ_ boolean であるとチェックすることができます:
console.log(typeof true); // 'boolean'
console.log(typeof false); // 'boolean'
変数が配列を含んでいるかをチェックする
JavaScript の変数が配列かどうかをチェックするには、組み込みの Array.isArray
があります。
JavaScript 配列の楽しいゴッチャは、それらが単なるオブジェクトであることです。
console.log(([]) instanceof Object); // true
console.log(typeof []); // 'object'
配列のダックタイプ方法は、.length
プロパティの存在を使用することです。しかし、配列のみが .length
プロパティを持つという規則はないので、これは非常に弱いです。このパターンは通常、次のように見えます:
function processList(maybeArray) {
if (!maybeArray.length) {
return []
}
return maybeArray.map(i => i); // 文字通りコピー
}
上記のコードは、実際には maybeArray
が配列かどうかをチェックしていません。それはするようなものですが、同じ行のコードである !maybeArray.length
は、実際には配列の場合は、0 ではない非偽性の長さを持つ必要があるとも述べています(空であってはならない)。
しかし Array.isArray を使用すると次のように機能します:
console.log(Array.isArray({})); // false
console.log(Array.isArray(new Map())); // false
console.log(Array.isArray(new Set())); // false
console.log(Array.isArray([])); // true
console.log(Array.isArray(new Array())); // true
配列の内訳をチェックする方法の詳細については、JavaScript 配列型チェック - 「is array」対オブジェクト深掘りを参照してください。フレーム間の通信がある場合、Array, Object, Date などの組み込み JavaScript データ型の大きな問題は、コンストラクタや instanceof
チェックが機能しないことです。
オブジェクトが特定のクラス/コンストラクタ関数のインスタンスであるかをチェックする
変数が React コンポーネントであることをチェックしたい場合、次のようにすることができます:
import React, { Component } from 'react';
const myComp = new Component();
function isReactComponent(maybeComponent) {
return maybeComponent instanceof Component;
}
isReactComponent(myComp);
// true
isReactComponent({});
// false
これはコンストラクタ関数でも機能します:
function Dog (name) {
this.name = name
}
const max = new Dog('Max');
console.log(max instanceof Dog); // true
もう一つ興味深いことは、プロトタイプチェーン/クラス階層を全て通じて動作することです:
console.log(({}) instanceof Object); // true
console.log((new Dog) instanceof Object); // true
オブジェクトがエラーかをチェックする
Error
はただのコンストラクタ/クラスです。したがって、React.Component
や Dog
クラスについてチェックできるのと同じ方法です:
function isError(maybeError) {
return maybeError instanceof Error;
}
isError(new Error('Something went wrong')); // true
isError(new EvalError()); // true
isError(new InternalError()); // true
isError(new RangeError()); // true
isError(new ReferenceError()); // true
isError(new SyntaxError()); // true
isError(new TypeError()); // true
isError(new URIError()); // true
MDN については、Fundamental Objects on MDN をご参照ください。
有効な JavaScript Date 文字列(解析可能な date-string)をチェックする
function isValidDateString(maybeDateString) {
return !Number.isNaN(Number(new Date(maybeDateString)));
}
console.log(isValidDateString('abcd')); // false
console.log(isValidDateString(1234)); // true
console.log(isValidDateString('2019-06-23T22:00:26.861Z')); // true
上記の関数は実際には何かが有効な文字列かどうかをチェックしません。それが有効な日付に変換可能かどうかをチェックしています。
さまざまな目的のために、これは不正な日付文字列を捕捉するでしょうし、数字のタイムスタンプを渡させるよりもコストをかけて読みにくくすることはありません。もっと適切な名前は isConvertibleToDate
かもしれません。数字を許可しないことは typeof maybeDateString === 'string'
を追加するだけの問題です。
有効な JavaScript Date かどうかをチェックする
何かが有効な日付かどう
かをチェックするには、それが日付に変換可能かどうかをチェックするのと同じアプローチをとります。
function isValidDateObject(maybeDate) {
return (
typeof maybeDate === 'object' &&
!Number.isNaN(Number(new Date(maybeDate))
);
}
isValidDateObject('abc'); // false
isValidDateObject(1234); // false
isValidDateObject('2019-06-23T22:00:26.861Z'); // false
isValidDateObject(new Date('2019-06-23T22:00:26.861Z')); // true
または instanceof
方法を適用することもできます:
function isValidDateObject(maybeDate) {
return maybeDate instanceof Date;
}
isValidDateObject('abc'); // false
isValidDateObject(1234); // false
isValidDateObject('2019-06-23T22:00:26.861Z'); // false
isValidDateObject(new Date('2019-06-23T22:00:26.861Z')); // true
これにはいくつかのクロスフレームの問題があり、誰かが独自のカスタムで非標準バージョンにグローバル
こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/hugo__df/javascript-data-type-check-cheatsheet-5b7d