JS を使用してデータ型を決定する 4 つの方法

JS を使用してデータ型を決定する 4 つの方法

序文

Javascript でのデータ型の判断は、実は JavaScript の非常に基本的な問題ですが、日常のプログラミングでも面接でも非常によくある問題です。

ECMAScript 仕様では、合計 7 つのデータ型が定義されており、以下に示すように、基本型と参照型の 2 つのカテゴリに分類されます。

基本型: 文字列、数値、ブール値、シンボル、未定義、Null

参照タイプ: オブジェクト

基本型は単純型とも呼ばれます。固定スペースを占有し、単純なデータ セグメントであるため、変数クエリ (つまり値によるアクセス) の速度を上げるためにスタックに格納されます。

参照型は複合型とも呼ばれます。その値のサイズは変化するため、スタックに格納することはできません。そうしないと、変数のクエリ速度が低下します。そのため、その値はヒープに格納され、変数に格納される値は、オブジェクトが格納されているメモリへのポインタ、つまりアドレスによるアクセスになります。参照型には、オブジェクトに加えて、関数、配列、正規表現、日付なども含まれます。

ECMAScript は緩く型付けされているため、特定の変数のデータ型を検出する方法が必要です。 JavaScript もこの問題に対するさまざまな方法を提供していますが、残念ながら、異なる方法では結果が異なります。

以下では、一般的に使用されている 4 つの方法を紹介し、各方法に存在する問題を簡単に分析します。

1. 型

typeof は、右側に単項式を取り、その式のデータ型を返す演算子です。返される結果は、そのタイプの文字列 (すべて小文字) の形式で表現され、数値、ブール値、シンボル、文字列、オブジェクト、未定義、関数などの 7 つのタイプが含まれます。

typeof''; // 文字列は有効 typeof1; // 数値は有効 typeofSymbol(); // シンボルは有効 typeoftrue; // ブール値は有効 typeofundefined; // undefined は有効 typeofnull; // オブジェクトは無効 typeof[]; // オブジェクトは無効 typeofnewFunction(); // 関数は有効 typeofnewDate(); // オブジェクトは無効 typeofnewRegExp(); // オブジェクトは無効

typeof 演算子は、わかりにくいものの技術的には正しい値を返すことがあります。

  • null を除く基本型の場合、正しい結果を返すことができます。
  • 関数を除く参照型の場合、オブジェクト型が常に返されます。
  • null の場合はオブジェクト型を返します。
  • 関数の場合は関数の型を返します。

その中で、null には独自のデータ型 Null があり、参照型の配列、日付、正規表現にも独自の特定の型があります。typeof がこれらの型を処理すると、プロトタイプ チェーンの先頭にある Object 型のみが返されます。これは正しいのですが、必要な結果ではありません。

2. インスタンス

Instanceof は、A が B のインスタンスであるかどうかを判断するために使用されます。式は、A instanceof B です。A が B のインスタンスである場合は true を返し、そうでない場合は false を返します。 ここで重要なのは、instanceof がプロトタイプを検出することです。擬似コードを使用して、その内部実行プロセスをシミュレートします。

インスタンス(A,B) = {
    varL = A.__proto__;
    varR = B.プロトタイプ;
    もし(L === R) {
        // A の内部プロパティ __proto__ は B のプロトタイプ オブジェクトを指します returntrue;
    }
    falseを返します。
}

上記のプロセスから、A の __proto__ が B のプロトタイプを指している場合、A は B のインスタンスであると見なされることがわかります。さらにいくつかの例を見てみましょう。

[] 配列のインスタンス; // true
{} オブジェクトのインスタンス; // true
newDate() インスタンス Date; // true
 
関数 Person(){};
newPerson() は Person のインスタンスです。
 
[] インスタンスオブオブジェクト; // true
newDate() インスタンスオブオブジェクト; // true
newPerson インスタンスオブオブジェクト; // true

instanceof は [] が Array のインスタンスであると判断できますが、[] は Object のインスタンスでもあると考えていることがわかりました。なぜでしょうか?

[]、配列、オブジェクトの関係を分析してみましょう。

instanceof から、[].__proto__ は Array.prototype を指し、Array.prototype.__proto__ は Object.prototype を指していることがわかります。最後に、Object.prototype.__proto__ は null を指し、プロトタイプ チェーンの終了を示します。したがって、[]、Array、および Object は内部的にプロトタイプ チェーンを形成します。

プロトタイプチェーンから、[] の __proto__ は直接 Array.prototype を指し、間接的に Object.prototype を指していることがわかります。したがって、instanceof の判定ルールによれば、[] は Object のインスタンスです。同様に、new Date() と new Person() も対応するプロトタイプ チェーンを形成します。したがって、instanceof は、2 つのオブジェクトがインスタンス関係にあるかどうかを判断するためにのみ使用できますが、オブジェクト インスタンスの特定のタイプを判断することはできません。

instanceof 演算子の問題は、グローバル実行コンテキストが 1 つだけであると想定していることです。 Web ページに複数のフレームが含まれている場合、実際には 2 つ以上の異なるグローバル実行環境が存在し、したがって 2 つ以上の異なるバージョンのコンストラクターが存在することになります。あるフレームワークから別のフレームワークに配列を渡す場合、渡された配列には、2 番目のフレームワークでネイティブに作成された配列とは別のコンストラクターがあります。

variframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[0].Array;
vararr = newxArray(1,2,3); // [1,2,3]
arr 配列インスタンス; // false

配列のこの問題を解決するために、ES5 では Array.isArray() メソッドが提供されています。このメソッドは、オブジェクトが作成された環境に関係なく、オブジェクト自体が配列型であるかどうかを確認するために使用されます。

if(Array.isArray(値)){
   //配列に対して何らかの操作を実行する}

Array.isArray() は基本的にオブジェクトの [[Class]] 値を検出します。[[Class]] は、オブジェクトの型情報を含むオブジェクトの内部プロパティです。その形式は [object Xxx] で、Xxx は対応する特定の型です。配列の場合、[[Class]] の値は [object Array] になります。

3. コンストラクター

関数 F が定義されると、JS エンジンは F にプロトタイプを追加し、プロトタイプにコンストラクター プロパティを追加して、F への参照を指すようにします。以下のように表示されます。

var f = new F()を実行すると、Fはコンストラクタとみなされ、fはFのインスタンスオブジェクトになります。このとき、Fプロトタイプ上のコンストラクタがfに渡されるため、f.constructor == Fとなります。

F はプロトタイプ オブジェクトのコンストラクターを使用して自分自身を参照していることがわかります。F をコンストラクターとして使用してオブジェクトを作成すると、プロトタイプのコンストラクターが新しく作成されたオブジェクトに継承されます。プロトタイプ チェーンの観点から見ると、コンストラクター F は新しいオブジェクトの型です。これを行うことの重要性は、新しいオブジェクトが誕生した後に追跡可能なデータ型を持つことができることです。

同様に、JavaScript の組み込みオブジェクトは内部的に次のように構築されます。

詳細:

1. null と undefined は無効なオブジェクトなので、コンストラクタは存在しません。これら 2 種類のデータは、他の手段で判断する必要があります。

2. 関数コンストラクターは不安定です。これは主にカスタム オブジェクトに反映されます。開発者がプロ​​トタイプを書き換えると、元のコンストラクター参照が失われ、コンストラクターはデフォルトで Object になります。

なぜオブジェクトになったのですか?

prototype は new Object() のリテラル値である { } に再割り当てされるため、new Object() は Object プロトタイプのコンストラクターを Object 自体である { } に渡します。

そのため、開発を標準化するためには、オブジェクト インスタンスの型が改ざんされないように、オブジェクト プロトタイプを書き換えるときにコンストラクターを再割り当てすることが一般的に必要になります。

4. 文字列

toString() は Object のプロトタイプ メソッドです。このメソッドが呼び出されると、デフォルトでは現在のオブジェクトの [[Class]] が返されます。これは、[オブジェクト Xxx] という形式の内部プロパティです。Xxx はオブジェクトのタイプです。

Object オブジェクトの場合、toString() を呼び出すだけで [object Object] が返されます。その他のオブジェクトの場合、正しい型情報を返すには、call / apply を通じて呼び出す必要があります。

Object.prototype.toString.call('') ; // [オブジェクト文字列]
Object.prototype.toString.call(1); // [オブジェクト番号]
Object.prototype.toString.call(true) ; // [オブジェクト ブール値]
Object.prototype.toString.call(Symbol()); //[オブジェクトSymbol]
Object.prototype.toString.call(undefined) ; // [オブジェクト Undefined]
Object.prototype.toString.call(null) ; // [オブジェクト Null]
Object.prototype.toString.call(newFunction()) ; // [オブジェクト関数]
Object.prototype.toString.call(newDate()) ; // [オブジェクト Date]
Object.prototype.toString.call([]) ; // [オブジェクト配列]
Object.prototype.toString.call(newRegExp()) ; // [オブジェクト RegExp]
Object.prototype.toString.call(newError()) ; // [オブジェクト Error]
Object.prototype.toString.call(document) ; // [オブジェクト HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] windowはグローバルオブジェクトglobalへの参照です

要約する

JS を使ってデータ型を判別する方法についての記事はこれで終わりです。JS データ型判別に関するより詳しい内容については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • js と jquery でデータ型を決定する 4 つの方法の概要
  • JavaScript でデータ型を判別する 4 つの方法
  • js データ型判定方法
  • js データ型とその判定方法の例
  • JSにおけるデータ型の正しい判定方法の例
  • JSにおける4つのデータ型判定方法
  • JavaScriptの型判定方法をいくつか紹介

<<:  Windows 64 ビットに MySQL を再インストールするチュートリアル (Zip バージョン、解凍バージョンの MySQL インストール)

>>:  Linux で NFS ファイル共有サーバーを構築するための詳細な手順

推薦する

nginx リバース プロキシでの proxy_pass の実装

フォーマットはシンプルです: proxy_pass URL; URL には、送信プロトコル (htt...

システム外のフォント参照とトランジション効果

コードをコピーコードは次のとおりです。 <span style="font-fami...

史上最もシンプルな MySQL データのバックアップと復元のチュートリアル (パート 2) (パート 36)

データのバックアップと復元パート2は次のとおりです基本的な概念:バックアップ、現在のデータまたはレコ...

MySQLでよく使われるSQLとコマンドの入力からデータベースの削除、そして終了まで

目次開始と停止データベース関連の操作データベーステーブル関連の操作制約関連デフォルトの制約高度なデー...

MySQL で複数の主キーが定義されているエラーの解決方法

主キーを作成するには 2 つの方法があります。 テーブルテーブル名を作成( フィールド名タイプ、 フ...

Dockerはプライベートライブラリイメージを完全に削除します

まず、インターネット上の一般的な慣行を見てみましょうデフォルトでは、プライベート ライブラリはイメー...

クロスブラウザの問題に対する 5 つの解決策 (要約)

簡単なレビュー: ブラウザの互換性の問題は、しばしば頭痛の種となります。ここでは、これらの問題を回避...

CSS3でハートを描く

成果を達成する要件/機能: CSS + HTML を使用してハートを描く方法。分析:正方形と 2 つ...

React Fiber構造の作成手順

目次リアクトファイバーの作成1. 始める前に2. React.renderから始める3. 終了リアク...

CSS のみを使用して折りたたまれたヘッダー効果を作成する方法の例コード

折りたたまれたヘッダーは、特別オファーや重要なお知らせなど、ユーザーにとって重要な情報を表示するのに...

MYSQL サブクエリとネストされたクエリの最適化例の分析

ゲーム史上最高スコアトップ100をチェックSQLコード cdb_playsgame ps から ps...

CSS3 を使用して 3D テキスト ホバー効果を実装するサンプル コード

この記事では、3D テキストのホバー変更効果を実現するための CSS3 のサンプル コードを紹介しま...

MySQLコンテナ間のレプリケーション構成例の詳細な説明

背景先週、会社で MySQL レプリケーションのトレーニングを受けたので、今週末は学んだことを実践す...

CSS 要素を表示および非表示にする 9 つの方法

Web ページの制作では、要素の表示と非表示は非常に一般的な要件です。この記事では、要素を表示したり...

クールなIoT大画面機能を実現するHTML+VUEページング

効果デモ.html <html> <ヘッド> <メタ文字セット=&qu...