序文JSON.stringify は非常に頻繁に使用される API ですが、コード プログラムに地雷を埋め込まないように、使用中に注意する必要がある機能があります。そこで、jsonStringify 関数の簡単なバージョンを一緒に実装してみましょう。 JSON.stringify の 6 つの機能特集1ブール値、数値、文字列のラップされたオブジェクトは、シリアル化時に自動的に対応する元の値に変換されます。 現在、次のようなオブジェクトがあります。 定数オブジェクト = { bol: 新しいブール値(true)、 num: 新しい数値(1)、 str: 新しい文字列(1) } typeofを使用してobjの各属性のデータ型を検出します。 typeof obj.bol; // オブジェクト typeof obj.num; // オブジェクト typeof obj.str; // オブジェクト 連載後 JSON.stringify(obj); // {"bol":true,"num":1,"str":"1"} この時点で、解析して各属性のデータ型を見つけます。 JSON を解析して文字列を解析する typeof stringifyObj.bol; // ブール値 typeof stringifyObj.num; // 数値 typeof stringifyObj.str; // 文字列 特集2NaN、Infinity、-Infinity、nullはすべて文字列化中にnullとして扱われます。 定数オブジェクト = { ナン: NaN、 無限: 無限、 ヌル: ヌル、 }; JSON.stringify(obj); // {"nan":null,"infinity":null,"null":null} 特集3オブジェクトがシリアル化されるときに、toJSON 関数がある場合、この関数によって返される値は、オブジェクト全体のシリアル化の結果になります。 定数オブジェクト = { ナン: NaN、 無限: 無限、 ヌル: ヌル、 JSON() { 「toJSON関数があります」を返します。 }, }; JSON.stringify(obj); // "toJSON関数があります" シリアル化後は、toJSON 関数の戻り値のみが存在し、残りのデータは無視されることがわかります。 ⚠️: toJSON 関数が Date にデプロイされているため、日付データは通常どおりシリアル化されます。これは、コンソールで Date.prototype.toJSON を出力することで確認できます。 定数オブジェクト = { 日付: 新しい Date(), }; JSON.stringify(obj); // {"date":"2021-10-08T11:43:31.881Z"} 特集4未定義、関数、シンボルは異なる動作をする オブジェクトのキーと値のペアとして: 値として: 定数オブジェクト = { 未定義: 未定義、 関数fn() {}, シンボル: シンボル() }; JSON.stringify(obj); // {} キーとして: 定数fn = 関数(){}; 定数オブジェクト = { [未定義]: 未定義、 [関数]: 関数() {}, [シンボル()]: シンボル() }; JSON.stringify(obj); // {} undefined、function、および symbol がオブジェクトのキーと値として使用されている場合、それらはシリアル化中に無視されます。 ⚠️: 上記の 3 種類のデータはシリアル化中に無視されるため、オブジェクトの元の順序が変わる可能性があります。 配列値として: const arr = [未定義、関数fn() {}、シンボル()]; JSON.stringify(arr); // [null,null,null] undefined、function、および symbol が配列値として使用された場合、それらはすべてシリアル化中に null に変換されます。 一人でいるとき: JSON.stringify(undefined); // 未定義 JSON.stringify(function () {}); // 未定義 JSON.stringify(Symbol()); // 未定義 undefined、function、および symbol が単独で存在する場合、シリアル化中にそれらはすべて undefined に変換されます。 特集5シリアル化中は、列挙可能なプロパティのみがシリアル化され、列挙不可能なプロパティは無視されます。 定数オブジェクト = { 名前: "nordon", 年齢: 18歳 }; // 年齢を列挙不可能なプロパティに変更する Object.defineProperty(obj, "age", { 列挙可能: false、 }); JSON.stringify(obj); // {"name":"nordon"} ⚠️: これにより、オブジェクトの元の順序も変更されます 特集6循環参照されたオブジェクトはシリアル化中に例外をスローします 定数オブジェクト = { 名前: "nordon", 年齢: 18歳 }; 定数p = { 名前: 'wy', オブジェクト } オブジェクトp = p JSON.stringify(obj); これにより、コンソールに例外がスローされます。
手動で文字列化を実装するJSON.stringify の機能のいくつかを理解したので、これらの機能に基づいて kack バージョンを実装できます。 実装する前に、カリー化を使用して、データ型検証用のいくつかのツール関数をカプセル化します。 const カリー化 = (fn, ...outParams) => { // fn 関数に必要なパラメータの数を取得します。const paramsLen = fn.length; 戻り値 (...引数) => { // すべてのパラメータを収集します。let params = [...outParams, ...args]; // パラメータがfnに必要なパラメータに達しない場合は、パラメータの収集を続けます。if (params.length < paramsLen) { カリー化(fn, ...params)を返します。 } fn(...params) を返します。 }; }; /** * type: タイプ - [オブジェクト配列]、[オブジェクト番号]など。 * source: データソース */ const judgeType = (type, source) => { Object.prototype.toString.call(source) === type を返します。 }; const isUndefined = currying(judgeType, "[オブジェクト Undefined]"); const isSymbol = currying(judgeType, "[オブジェクト シンボル]"); const isFunction = currying(judgeType, "[オブジェクト Function]"); const isObject = currying(judgeType, "[object Object]"); const isNull = currying(judgeType, "[オブジェクト Null]"); 直接的なコードは次のとおりです: 関数jsonStringify(データ) { type = typeofデータとします。 if (isNull(データ)) { // null は直接文字列 'null' を返します 「null」を返します。 } そうでない場合 (data.toJSON && typeof data.toJSON === "function") { // toJSON 関数を設定し、toJSON によって返されたデータを直接使用し、他のデータは無視します return jsonStringify(data.toJSON()); } そうでない場合 (Array.isArray(data)) { 結果 = [] とします。 //配列の場合、配列内の各項目は異なる型である可能性があります data.forEach((item, index) => { if (isUndefined(item) || isSymbol(item) || isFunction(item)) { 結果[インデックス] = "null"; } それ以外 { 結果[インデックス] = jsonStringify(item); } }); 結果 = "[" + 結果 + "]"; 結果を返します。replace(/'/g, '"'); } そうでない場合 (isObject(データ)) { // 通常のオブジェクトを処理する let result = []; Object.keys(data).forEach((item, index) => { if (typeof item !== "シンボル") { //キーがシンボルオブジェクトの場合、if(を無視する データ[項目] !== 未定義 && typeof data[item] !== "function" && typeof data[item] !== "symbol" ){ //キー値が未定義、関数、またはシンボルの場合は無視します。result.push( '"' + 項目 + '"' + ":" + jsonStringify(data[item]) ); } } }); 戻り値: ("{" + 結果 + "}").replace(/'/g, '"'); } そうでない場合 (type !== "object") { 結果 = データとします。 //data は基本データ型である可能性があるので、ここで処理します if (Number.isNaN(data) || data === Infinity) { //NaN および Infinity のシリアル化は「null」を返します 結果 = "null"; } そうでない場合 (isUndefined(データ) || isSymbol(データ) || isFunction(データ)) { // 関数のシリアル化は undefined を返すため、undefined およびシンボル return undefined と一緒に処理されます。 } そうでない場合 (type === "文字列") { 結果 = '"' + データ + '"'; } String(結果)を返します。 } } この時点で、JSON.stringify の簡易版は完成しました。まだ多くの機能が欠けていますが、主にアイデアを提供しています。コアコメントはコード内に注釈が付けられており、コードと上記の機能と一緒に理解できます。 要約するJSON.stringify の実装とその 6 つの主要機能に関するこの記事はこれで終わりです。JSON.stringify のより簡略化されたバージョンとその機能については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: W3C が推奨するモバイル Web マークアップ言語 XHTML Basic 1.1
>>: 非常に詳細な MySQL8.0.22 のインストールと設定のチュートリアル
目次1. レシピ集1.1 プロジェクトの背景1.2 テクノロジースタック1.3 開発環境1.4. プ...
チュートリアルシリーズMySQL シリーズ: MySQL リレーショナル データベースの基本概念My...
目次1. 文法2. 例3. その他の関連方法長い間、reduce() メソッドの具体的な使い方を理解...
Linux 仮想マシン: VMware + Ubuntu 16.04.4 Windows ネイティブ...
一般的な開発ニーズとして、要素の一部を必要になるまで折りたたんでおきたいことが挙げられます。 Boo...
nginx 設定ファイルのパスを表示する nginx -t 経由nginx -t コマンドの本来の機...
この記事では、無限ループスクロールを実現するためのReactの具体的なコードを参考までに紹介します。...
目次1. 手ぶれ補正機能とは何ですか? 1. なぜ手ぶれ補正機能が必要なのでしょうか? 2. 手ぶれ...
Bツリーインデックス異なるストレージ エンジンでは、異なるストレージ構造を使用する場合もあります。た...
同僚から、LINUX サーバー上の多くのコマンドが (コマンドが見つかりません) というプロンプトで...
序文現在、私は Beetlex のデータ分析プラットフォームに取り組んでいます。この製品の開発では、...
エラーのスクリーンショット例外が発生した場所が見つかりません。解決策: リソースディレクトリにlog...
序文開発プロセスでは、ブラウザレベルでユーザーが実行した操作を記憶するなど、同様の要件に遭遇すること...
この記事では、ショッピングカートを実装するためのVue.jsフレームワークの具体的なコードを参考まで...
現在のページへのリンク。 -------------------一般的な使用法は次のとおりです。 &...