別再被坑了!JavaScript の型検出のベストプラクティス#
JavaScript では、変数の型を判断する必要がよくあります。この要件はプログラミングで非常に一般的であり、異なるタイプのデータがコードのロジックに影響を与えるからです。
JavaScript には、データ型を検出するためのいくつかの方法が用意されており、それぞれに利点と欠点があります。
Object.prototype.toString.call()
#
これは最も汎用性のある方法です。これにより、組み込みの JavaScript のすべてのタイプ、基本タイプおよび複雑なタイプを正確に識別することができます。どのようなデータを渡しても、統一された形式の文字列を返し、そのデータの実際のタイプを示します。
これは、オブジェクトの内部の [[Class]]
プロパティを呼び出すことによって動作します。このプロパティは読み取り専用であり、変更することはできないため、非常に信頼性があります。
利点:
- 幅広い範囲を識別でき、基本タイプと複雑なタイプの両方を識別できます。
- オブジェクト自体の
toString()
メソッドの影響を受けません。 - 結果の形式が統一されており、解析が容易です。
欠点:
- 書き方がやや冗長です。
- カスタムタイプの場合、
[object Object]
のような結果しか得られず、さらにタイプを区別することはできません。
function detectType(data) {
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
}
console.log(detectType(123)); // 'number'
console.log(detectType('abc')); // 'string'
console.log(detectType(true)); // 'boolean'
console.log(detectType(null)); // 'null'
console.log(detectType(undefined)); // 'undefined'
console.log(detectType([])); // 'array'
console.log(detectType({})); // 'object'
console.log(detectType(function () {})); // 'function'
console.log(detectType(new Date())); // 'date'
console.log(detectType(new RegExp())); // 'regexp'
console.log(detectType(new Error())); // 'error'
typeof
#
この演算子は最も一般的に使用され、書き方も簡単です。基本タイプと関数を識別することができますが、複雑なタイプの識別能力は限られています。
利点:
- 使用が簡単です。
- 基本タイプと関数を識別できます。
欠点:
- 配列と通常のオブジェクトを区別することができません。
typeof null
の結果は'object'
です。Date
、RegExp
などの組み込みオブジェクトのタイプを識別できません。
console.log(typeof 123); // 'number'
console.log(typeof 'abc'); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' (これは歴史的なバグです)
console.log(typeof []); // 'object'
console.log(typeof {}); // 'object'
console.log(typeof function () {}); // 'function'
instanceof
#
instanceof
演算子は、オブジェクトのプロトタイプチェーン内にコンストラクタの prototype
プロパティが存在するかどうかをテストするために使用されます。
利点:
- オブジェクトが特定のクラスまたはコンストラクタに属しているかどうかを確認できます。
欠点:
- オブジェクトのタイプのみをチェックできます。基本タイプをチェックすることはできません。
- 複数のタイプを識別するには、複数回呼び出す必要があります。
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(function () {} instanceof Function); // true
console.log(new Date() instanceof Date); // true
console.log(new RegExp() instanceof RegExp); // true
console.log(new Error() instanceof Error); // true
console.log(123 instanceof Number); // false
console.log('abc' instanceof String); // false
console.log(true instanceof Boolean); // false
constructor
#
constructor
はオブジェクトのプロパティであり、そのオブジェクトを作成したコンストラクタを指します。これを使用してオブジェクトのタイプを判断することができます。
利点:
- 多くのオブジェクトタイプを識別できます。カスタムタイプも含まれます。
欠点:
- オブジェクトの
constructor
プロパティが変更されている場合、誤った結果が得られます。 null
とundefined
にはconstructor
プロパティがありません。
console.log((123).constructor === Number); // true
console.log('abc'.constructor === String); // true
console.log(true.constructor === Boolean); // true
console.log([].constructor === Array); // true
console.log({}.constructor === Object); // true
console.log(function () {}.constructor === Function); // true
console.log(new Date().constructor === Date); // true
console.log(new RegExp().constructor === RegExp); // true
console.log(new Error().constructor === Error); // true
結論#
完全かつ正確な型の識別が必要な場合は、Object.prototype.toString.call()
を使用することが最善です。
基本的なタイプの単純な区別のみが必要な場合は、typeof
が十分です。
オブジェクトが特定のタイプに属しているかどうかをチェックする場合は、instanceof
を使用できます。
実際のアプリケーションでは、具体的な要件に応じて適切な方法を選択することができます。
結び#
前回、私は使用されていないリポジトリを一括でクリーンアップするツールを開発しました。興味があれば、ぜひご覧ください!😊
記事の紹介: https://mp.weixin.qq.com/s/t7lgc6b7xJiNhfm5vWo5-A
GitHub リポジトリのリンク: https://github.com/yaolife ng0629/del-repos
このツールが役に立った場合は、私の GitHub リポジトリに スターを付ける のを忘れないでください ⭐!あなたのサポートは私の前進の原動力です!
お読みいただきありがとうございました。また次回お会いしましょう!