👶

javascriptのデータタイプ判定

2023/04/09に公開

はじめに

こんにちは。
full-stack developerを目指しているShenです。
最近コードレビューを受けて、データタイプの判定のところ曖昧だった部分がたくさんあったので、ここで整理指定と思います。

データタイプ判定

プリミティブ値のタイプ判定

typeofはプリミティブ値しか判定できません。

判定できるもの

文字列

typeof ''; // string

数値

typeof 1; // number

真偽値

typeof true; // boolean

undefined

typeof undefined; // undefined

関数

function testA() {return null};
const testB = () => {return null};

typeof testA; // function
typeof testB; // function

BigInt

typeof 9007199254740991n; // bigint

Symbol

typeof Symbol('test'); // symbol

オブジェクト

typeof {}; // object

判定できないもの

null

typeof null; // obejct

配列

typeof []; // object

参照型判定

参照型は判定できますが、プリミティブ値は判定できません。
配列

[] instanceof Array; // true

オブジェクト

{} instanceof Object; // true

怪しいのは以下のことです。

[] instanceof Object; // true
function test(){};
test instanceof Function; // true
test instanceof Object; // true

なぜなら、instanceof演算子は、あるコンストラクターのprototypeプロパティが、あるオブジェクトのプロトタイプチェーンの中のどこかに現れるかどうかを検査します。配列または関数は Objectクラスにも属しています。配列はプロトタイプ的にObjectを継承しているためです。

constructor

すべてのオブジェクトインスタンスは、コンストラクタオブジェクトを介してそのコンストラクタ関数にアクセスできます。基本型とオブジェクトの両方を検出できますが、nullとundefinedを検出することはできません。

const regex = /^$/;
console.log(regex.constructor === RegExp); //true
console.log(regex.constructor === Object); //false

console.log((10).constructor === Number); //true
console.log([].constructor === Array); //true

Object.prototype.toString.call()

ObjectのプロトタイプにあるtoStringメソッドを取得し、メソッドを実行するには、toStringメソッド内のthisが最初の引数の値を指すようにします。これがnullでも取得できます。

Object.prototype.toString.call(null); // [object Null]

ただ、property pollutionによって、以下のようなことが発生してしまいます。

const myDate = new Date();
Object.prototype.toString.call(myDate);     // [object Date]

myDate[Symbol.toStringTag] = 'notDate';
Object.prototype.toString.call(notDate);     // [object notDate]

終わりに

簡単なものですが、罠があったところたくさんありました。個人的には、constructorは一番使いやすいかなと思いました。nullとundefinedを判定することは極少ないと思っています。

Discussion