JSON.stringify の簡易版の実装とその 6 つの主要機能の詳細な説明

JSON.stringify の簡易版の実装とその 6 つの主要機能の詳細な説明

序文

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; // 文字列

特集2

NaN、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);

これにより、コンソールに例外がスローされます。

キャッチされない TypeError: 循環構造を JSON に変換しています --> コンストラクター 'Object' を持つオブジェクトから開始 | プロパティ 'p' -> コンストラクター 'Object' を持つオブジェクト --- プロパティ 'obj' は JSON.stringify (<anonymous>) で循環を閉じます

手動で文字列化を実装する

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 をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JSON.stringify() の 5 つの秘密の機能の説明
  • JSON オブジェクトと文字列間の変換について説明します。JSON.stringify(obj) と JSON.parse(string)
  • JSON.stringifyがJSONを変換するときに日付と時刻が不正確になる問題の解決方法
  • JSON.stringify の 9 つの機能と変換ルールを学ぶ

<<:  W3C が推奨するモバイル Web マークアップ言語 XHTML Basic 1.1

>>:  非常に詳細な MySQL8.0.22 のインストールと設定のチュートリアル

推薦する

Vue の計算プロパティとリスナーの使用の概要

1. 計算プロパティとリスナー1.1 計算プロパティ <!DOCTYPE html> &...

JavaScript でオブジェクトをトラバースする 5 つの方法 サンプルコード

目次準備する5つの武器…のためにオブジェクト.キーオブジェクト.getOwnPropertyName...

特定のシンボルで複数の行と列に分割するMySQLの例

一部の障害コード テーブルでは、履歴またはパフォーマンス上の理由から、次の設計パターンが使用されます...

Google 翻訳ツール: 多言語ウェブサイトを素早く実装

Google Chinaは、ウェブサイトやブログを素早く簡単に多言語化できる翻訳ツールをリリースした...

nginx を最適化する 6 つの方法

1. Nginxの同時実行性を最適化する [root@proxy ~]# ab -n 2000 -c...

Dockerコンテナが停止できない問題の解決方法

解決策は次のとおりです。 1. コンテナを強制削除する docker rm -f ジェンキンス2. ...

Ubuntu環境でPHPとNginxをコンパイルしてインストールする方法

この記事では、Ubuntu 環境で PHP と Nginx をコンパイルしてインストールする方法につ...

Ubuntu で時刻同期に NTP を使用する

NTP は、ネットワーク上で時間を同期するための TCP/IP プロトコルです。通常、クライアントは...

jsは水平および垂直スライダーを実現します

最近、練習プロジェクトをしていたときにスライダーを使う必要があったので、調べてみました。まず、水平ス...

Linux インストール Redis 実装プロセスとエラー解決

今日、redis をインストールしたところ、今までになかったいくつかのエラーが発生しました。ここで記...

ウェブサイトレイアウトにおける CSS の計算関数 calc の例

calc は数値を計算するために使用される CSS 関数です。長さ、角度、時間などを計算できます。 ...

VMware仮想マシンにLinux(CentOS)をインストールするための詳細な構成手順

CentOS7をダウンロード私がダウンロードしたイメージはCentOS-7-x86_64-DVD-1...

DockerとVMwareの競合を解決する

1. Dockerの起動の問題:問題は解決しました: Hyper-V をオンにする必要があります (...

Linux 上でプライベート Git サーバーを構築するための詳細なチュートリアル

1. サーバーのセットアップリモート リポジトリは実際にはローカル リポジトリと何ら変わりなく、純粋...

CSS リセットスタイルリセットの実装例

はじめに: すべてのブラウザには、「ユーザー エージェント スタイル シート」と呼ばれる、すべてのペ...