序文Javascript でのデータ型の判断は、実は JavaScript の非常に基本的な問題ですが、日常のプログラミングでも面接でも非常によくある問題です。 ECMAScript 仕様では、合計 7 つのデータ型が定義されており、以下に示すように、基本型と参照型の 2 つのカテゴリに分類されます。
基本型は単純型とも呼ばれます。固定スペースを占有し、単純なデータ セグメントであるため、変数クエリ (つまり値によるアクセス) の速度を上げるためにスタックに格納されます。 参照型は複合型とも呼ばれます。その値のサイズは変化するため、スタックに格納することはできません。そうしないと、変数のクエリ速度が低下します。そのため、その値はヒープに格納され、変数に格納される値は、オブジェクトが格納されているメモリへのポインタ、つまりアドレスによるアクセスになります。参照型には、オブジェクトに加えて、関数、配列、正規表現、日付なども含まれます。 ECMAScript は緩く型付けされているため、特定の変数のデータ型を検出する方法が必要です。 JavaScript もこの問題に対するさまざまな方法を提供していますが、残念ながら、異なる方法では結果が異なります。 以下では、一般的に使用されている 4 つの方法を紹介し、各方法に存在する問題を簡単に分析します。 1. 型typeof は、右側に単項式を取り、その式のデータ型を返す演算子です。返される結果は、そのタイプの文字列 (すべて小文字) の形式で表現され、数値、ブール値、シンボル、文字列、オブジェクト、未定義、関数などの 7 つのタイプが含まれます。 typeof''; // 文字列は有効 typeof1; // 数値は有効 typeofSymbol(); // シンボルは有効 typeoftrue; // ブール値は有効 typeofundefined; // undefined は有効 typeofnull; // オブジェクトは無効 typeof[]; // オブジェクトは無効 typeofnewFunction(); // 関数は有効 typeofnewDate(); // オブジェクトは無効 typeofnewRegExp(); // オブジェクトは無効 typeof 演算子は、わかりにくいものの技術的には正しい値を返すことがあります。
その中で、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 をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Windows 64 ビットに MySQL を再インストールするチュートリアル (Zip バージョン、解凍バージョンの MySQL インストール)
>>: Linux で NFS ファイル共有サーバーを構築するための詳細な手順
フォーマットはシンプルです: proxy_pass URL; URL には、送信プロトコル (htt...
コードをコピーコードは次のとおりです。 <span style="font-fami...
データのバックアップと復元パート2は次のとおりです基本的な概念:バックアップ、現在のデータまたはレコ...
目次開始と停止データベース関連の操作データベーステーブル関連の操作制約関連デフォルトの制約高度なデー...
主キーを作成するには 2 つの方法があります。 テーブルテーブル名を作成( フィールド名タイプ、 フ...
まず、インターネット上の一般的な慣行を見てみましょうデフォルトでは、プライベート ライブラリはイメー...
簡単なレビュー: ブラウザの互換性の問題は、しばしば頭痛の種となります。ここでは、これらの問題を回避...
成果を達成する要件/機能: CSS + HTML を使用してハートを描く方法。分析:正方形と 2 つ...
目次リアクトファイバーの作成1. 始める前に2. React.renderから始める3. 終了リアク...
折りたたまれたヘッダーは、特別オファーや重要なお知らせなど、ユーザーにとって重要な情報を表示するのに...
ゲーム史上最高スコアトップ100をチェックSQLコード cdb_playsgame ps から ps...
この記事では、3D テキストのホバー変更効果を実現するための CSS3 のサンプル コードを紹介しま...
背景先週、会社で MySQL レプリケーションのトレーニングを受けたので、今週末は学んだことを実践す...
Web ページの制作では、要素の表示と非表示は非常に一般的な要件です。この記事では、要素を表示したり...
効果デモ.html <html> <ヘッド> <メタ文字セット=&qu...